Почему strcpy() также копирует \n? Могу ли я избавиться от него?

Я отладил функцию, и она работает. Так что да, самообучение C, кажется, идет хорошо. Но я хочу сделать его лучше. То есть он читает такой файл:

want 
to 
program
better

И помещает каждую отдельную строку строки в массив строк. Однако вещи становятся странными, когда я что-то распечатываю. Насколько я читал, strcpy() должен просто копировать строку до символа \0. Если это правда, то почему следующая печать строки нужна и \n? Это похоже на то, что strcpy() также скопировал \n и завис там. Я хочу избавиться от этого.

Мой код для копирования файла ниже. Я не включил всю программу, потому что не верю, что это имеет отношение к происходящему. Я знаю, что проблема здесь.

void readFile(char *array[5049]) 
{
    char line[256]; //This is to to grab each string in the file and put it in a line. 
    int z = 0; //Indice for the array

    FILE *file;
    file = fopen("words.txt","r");

    //Check to make sure file can open 
    if(file == NULL)
    {
        printf("Error: File does not open.");
        exit(1);
    }
    //Otherwise, read file into array  
    else
    {
        while(!feof(file))//The file will loop until end of file
        {
           if((fgets(line,256,file))!= NULL)//If the line isn't empty
           {
             array[z] = malloc(strlen(line) + 1);
             strcpy(array[z],line);
             z++;
           }    
        }
    }
    fclose(file);
}

Итак, теперь, когда я делаю следующее:

     int randomNum = rand() % 5049 + 1;

     char *ranWord = words[randomNum];
     int size = strlen(ranWord) - 1; 
     printf("%s",ranWord);
     printf("%d\n",size);
     int i; 
     for(i = 0; i < size; i++)
     {
          printf("%c\n", ranWord[i]);
     }

Он распечатывает:

these 
6
t
h
e
s
e

Разве он не должен распечатать следующее?

 these6
 t
 h
 e
 s
 e

Итак, единственное, что я могу понять, это то, что когда я помещаю строки в массив, он также помещает туда \n. Как я могу избавиться от этого?

Как всегда, с уважением. ГикиОмега


person GeekyOmega    schedule 31.07.2012    source источник
comment
Является ли \n == \0, если нет, то копируем. Простой. Если вы хотите избежать этого, напишите свой собственный strcpy(). Или манипулируйте позицией символа '\0', если символы новой строки всегда находятся в конце.   -  person jn1kk    schedule 31.07.2012
comment
Не используйте feof(); вам это не нужно, если вам не нужно различать ошибку и EOF. помещая fgets(), цикл достаточно хорош и намного проще.   -  person wildplasser    schedule 31.07.2012
comment
Я считаю это закрытым. Спасибо всем, кто ответил на него.   -  person GeekyOmega    schedule 07.08.2012


Ответы (2)


fgets также считывает \n, это часть вашего входного файла. Если вы хотите избавиться от него, сделайте что-то вроде:

int len = strlen(line);
if (len > 0 && line[len-1] == '\n') line[len-1] = '\0';
person Keith Randall    schedule 31.07.2012
comment
еще лучше: if (len > 0 && line[len-1] == '\n') line[--len] = '\0'; - person wildplasser; 31.07.2012
comment
Спасибо вам обоим. Это действительно решило проблему. Является ли fgets() действительно плохим способом сделать это? Мог ли я избежать чего-то подобного, если бы вместо этого использовал fread()? - person GeekyOmega; 31.07.2012
comment
fread имеет такое же поведение. Вы можете избежать этой проблемы, используя язык, отличный от C, который имеет более продвинутую встроенную обработку строк/ввода (python, Java,...). - person Keith Randall; 31.07.2012
comment
Я не знаю мнения других людей, но fread() звучит как еще худший способ сделать это; чтение байтов по одному, а затем преобразование намного более утомительно и подвержено ошибкам, чем чтение в строке и простое удаление завершающей новой строки. Вы должны иметь дело с новыми строками каким-то образом, так что это может быть как можно более чистым способом. - person Dennis Meng; 31.07.2012
comment
Спасибо всем. Как я уже сказал, я учусь. Кто-то сказал мне, что fread() лучше, но лично я предпочитаю fgets(). Я ценю помощь каждого. - person GeekyOmega; 31.07.2012

Например, когда вы читаете первую строку, вы на самом деле читаете «хочу\n», потому что разрыв строки является частью строки. Таким образом, вы получаете «хочу\n\0». То же самое верно и для других строк (кроме последней, если в вашем файле нет пустой строки в конце).

person Rodrigo Guedes    schedule 31.07.2012