Случайные восклицательные знаки в потоке из malloc (), но исчезают, если строка удалена?Я развращаю кучу? - PullRequest
0 голосов
/ 11 июля 2011

Я не часто работаю с C, поэтому, пожалуйста, извините за любые ошибки, которые я мог бы совершить в плане стиля кодирования: P В настоящее время я получаю сообщение об ошибке, на котором я немного озадачен: когда я включаю строку tokenCopy = malloc(sizeof(fileSize));, Я получаю случайный случайный восклицательный знак примерно на 1/4 пути через вывод файла в std, но если строка удаляется / комментируется, данные отображаются, как и ожидалось:

MAY      +1.32      D1      1002
JUNE     -1.57      D3      201
JULY      -2.37      D4      478
AUGUST      +5.03      D2      930
SEPTEMBER      -3.00      D1      370
OCTOBER      +7.69      D1      112

и фактическаявывод, который я получаю, когда строка на месте:

MAY      +1.32      D1      1002
JUNE      -1.57      D3      2!

и соответствующий код:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>


    /**
     * Machine struct - three column
     **/

    /**
     * Parses the input file, size is the size of name
     **/

    char parseInputFile(char *name, int size) {
            FILE *fp;

          if ((fp = fopen(name,"r")) == NULL) {
                printf("Cannot open file %s\n", name);
                return 1;
            }
            else {
                int fileSize;
                fileSize = 0;
                char *fileContent;
                char *processedFileContent;

                //get file size
                fseek(fp, 0, SEEK_END);
                fileSize = ftell(fp);
                fseek(fp, 0, SEEK_SET);

                //allocate
                fileContent = malloc(sizeof(fileSize));
                processedFileContent = malloc(sizeof(fileSize));

                //read
                char c;
                int g;
                g=0;

                while((c = getc(fp)) != EOF) {
                    fileContent[g] = c;
                    g++;
                }

                //process
                char delim[6] = "      ";
                char *tokenCopy;
                tokenCopy = malloc(sizeof(fileSize));

                strcpy(tokenCopy, fileContent);
                char *tokens = strtok(tokenCopy, delim);

                while (tokens) {
                    tokens = strtok(NULL, delim);
                }

                puts(fileContent);
                //printf("File Size: %i \n",fileSize);
                //puts(tokenCopy);
                return *processedFileContent;
            }
    }

    int main(int argc, char *argv[])
    {
            //char *input;
            if (argc == 1)
                puts("You must enter a filename");
            else {
                int size = sizeof(argv[1]);
                parseInputFile(argv[1],size);
            }
            return 0;
    }

Может ли кто-нибудь подсказать, что я делаю неправильно (илиесли мой код вызывает проблемы сам по себе)?

Ответы [ 2 ]

3 голосов
/ 11 июля 2011

Вы помещаете размер файла в fileSize, но затем выделяете только место для хранения int, что sizeof(FileSize) даст вам.

Эти две строки

            fileContent = malloc(sizeof(fileSize));
            processedFileContent = malloc(sizeof(fileSize));

должно быть (при условии, что вы будете воспринимать текст, который вы читаете, как строку):

            fileContent = malloc(fileSize+1);
            processedFileContent = malloc(fileSize+1)

и, прочитав содержимое файла, вы должны поставить '\ 0' в полеконец.

Тем не менее, я действительно не понимаю, чего вы пытаетесь достичь, используя strtok().Если вам нужно разделить только три компонента в каждой строке, вы можете сделать это намного проще, пока читаете файл, поскольку вы читаете его по одному символу за раз.

Если вы немного подробнее расскажете о том, что выпытаясь достичь, у нас может быть другой совет.

ОБНОВЛЕНИЕ ПОСЛЕ КОММЕНТАРИИ НИЖЕ

Вы должны сделать шаг назад и пересмотреть свою проблему, так как я подозреваю, что вы не понимаете 'не нужно хранить какую-либо строку вообще.Первое значение - это название месяца, которое может быть сохранено как целое число, второе - двойное (или число с плавающей запятой), третье выглядит как ' Dx ' с x , варьирующимся от 1 до4, снова это может быть целое число.Кажется, это имя датчика, поэтому я подозреваю, что его можно было бы кодировать целым числом, так как их наверняка будет конечное число.И четвертое явно другое целое число.

С диким предположением о значении этих полей ваша структура будет выглядеть примерно так:

struct val {
   int month;
   double value;
   int sensor;
   int var;
}

Теперь вы можете получить значения каквы переходите на один символ за раз или читаете целую строку и получаете оттуда значения.

Переход на один символ за раз не потребует дополнительного пространства, но приведет к увеличению длины программы (полной 'если'и' пока ').Чтение строки будет немного легче, но вам потребуется обработать максимальный размер строки.

Правильное структурирование функций вам очень поможет:

 do {
   if ((c = get_month(fp, &month)) != EOF) 
     if ((c = get_value(fp, &value)) != EOF)
       if ((c = get_sensor(fp, &sensor)) != EOF)
         if ((c = get_var(fp, &var)) != EOF)
           measures = add_data(measures, month, value, sensor, var);
 } while (c != EOF);
 return measures

Где measures может быть связанным списком или массивом ваших структур с изменяемым размером, и при условии, что вы перейдете на один символв то время.

Есть много других деталей, которые вы должны установить, прежде чем закончите, я надеюсь, что это поможет вам найти правильное направление.

3 голосов
/ 11 июля 2011

Ваша строка delims не заканчивается нулем.

Кроме того, разделители сопоставляются посимвольно, поэтому бесполезно повторять пробел шесть раз, и ваш вызов strtok не будет соответствовать серии из шести пробелов. Возможно, вам нужно что-то вроде strpbrk.

...