printf ограничен тремя символами? - PullRequest
1 голос
/ 19 сентября 2011

Я сократил эту функцию до причины, вызывающей проблему, но я попытаюсь дать достаточно контекста этой проблеме, не заставляя вас просматривать строки и строки текста:

По сути, я кормлюстрока в функцию ниже, и если первый символ в строке является #, то я хочу напечатать строку.Вот и все.

Однако при этом печатаемые строки обрезаются по три символа в длину.Так, например, где входная строка " # Hello, World! " будет напечатана только " # H ".

Я получаю свои входные строкииспользуя fgets () из следующего входного файла:

# Testing######## More

И вывод выглядит следующим образом:

# T######## M

Вот соответствующие урезанные функции:

int main(int argc,char *argv[]){

    FILE    *input;
    lineResponse response;

    //If a filename was specified, the file exists, and it is openable
    if(argv[1] != NULL && (input = fopen(argv[1],"r")) != NULL){
        char *currentLine = "";
        //Loop through the lines
        while(fgets(currentLine,sizeof(input),input)){
            response = parseLine(currentLine);
        }
    }

    fclose(input);

    getchar();

}

lineResponse parseLine(char *line){
    lineResponse response = {0,NULL}; //0 is the default lineType, denoting a line that cannot be parsed
    if(line != NULL){
        if(line[0] == '#'){
            printf("%s\n",line);
        }
    }
    return response;
}

Возвращение lineResponse не имеет отношения к этой проблеме.Что может быть причиной обрезки?Если вам нужен более обширный пример, я могу привести один.

Ответы [ 2 ]

6 голосов
/ 19 сентября 2011
char *currentLine = "";
 //Loop through the lines
 while(fgets(currentLine,sizeof(input),input)){

Это ваша проблема. Вы объявляете указатель на символ и присваиваете ему строковый литерал ... затем пытаетесь прочитать его. Вы также, кажется, не понимаете второй аргумент fgets; он читает на единицу меньше этого количества символов и завершает буфер с \0. Также имейте в виду, что переводы строки хранятся в буфере и должны быть удалены, если они вам не нужны.

Это должно быть:

char currentLine[1024]; /* arbitrary - needs to be big enough to hold your line */
while(fgets(currentLine,1024,input)) {

Строковые литералы (например, char* = "This is a string literal") являются неизменяемыми (только для чтения). Они создаются во время компиляции.

4 голосов
/ 19 сентября 2011

Проблема должна заключаться в том, как вы читаете строку. Поскольку вы комментируете, что читаете с fgets(), я предполагаю, что вы работаете на 32-битной машине и у вас есть какой-то код, похожий на:

char buffer[128];

if (fgets(&buffer, sizeof(&buffer), stdin))
{
    lineResponse r = parseLine(buffer);
    ...
}

Существуют и другие смутно похожие методы:

char *buffer;
if (fgets(buffer, sizeof(buffer), stdin))
    ...

Здесь происходит то, что вы задаете неправильный размер (и неправильный адрес) для fgets(), и он видит размер всего 4, что означает, что он может хранить только 3 символа плюс завершающий NUL '\0'.

Правильный код может быть:

char buffer[128];

if (fgets(buffer, sizeof(buffer), stdin))
{
    lineResponse r = parseLine(buffer);
    ...
}

Или:

char *buffer = malloc(2048);
// error check memory allocation!
if (fgets(buffer, 2048, stdin))
    ...

Теперь код виден ...

Ваш код отображается как:

    char *currentLine = "";
    //Loop through the lines
    while(fgets(currentLine,sizeof(input),input)){
        response = parseLine(currentLine);

Это действительно соответствует (более или менее) гипотезе char *buffer;, которую я выдвинул. У вас есть добавленный твик, который вы используете sizeof(input), где вы объявляете FILE *input;. Вам нужно адаптировать мою вторую предложенную альтернативу, если вы сохраняете currentLine как char *, или в качестве альтернативы (проще, потому что нет динамически выделенной памяти для утечки), используйте:

    char currentLine[2048];
    //Loop through the lines
    while (fgets(currentLine, sizeof(currentLine), input))
    {
        response = parseLine(currentLine);
        ...
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...