Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Последний символ - два раза


Автор: Валерия 7.4.2007, 14:05
Код

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

int main(void)
{
    FILE *stream;
    char string[]=" \n";
    char *msg;

    stream = fopen("D:\\1.txt", "r");

    while (!feof(stream)){
        fgets(msg, strlen(string), stream);
        printf("%s", msg);
    }

    fclose(stream);
   return 0;
}


Файл 1.txt:
Код
First
Second
Third


Программа выдает
Код
First
Second
Thirdd


Почему последний символ выводиться на экран дважды?

Автор: apook 7.4.2007, 14:14
Код

    while (!feof(stream))
    {
        fgets(msg, strlen(string), stream);
        if(!feof(stream))
           printf("%s", msg);
         }

попробуй так т.е проверку на конец файла сделать дважды

Автор: Валерия 7.4.2007, 14:25
Спасибо, помогло.

Автор: codelord 7.4.2007, 14:32
что то не понятно как у тебя вообще заработала эта программа, у меня ошибки, собственно и понятно, зачем тебе
string если ты берешь его длину, при этом его длина как раз заведомо меньше даже небольшой строки, делать проверки два раза
тоже не красиво.
Код

#include <string.h>
#include <stdio.h>
#define strl 256
int main(void)
{
    FILE *stream;
    char msg[strl];
    stream = fopen("D:\\1.txt", "r");
    if(!stream)return 0;
    while (!feof(stream)){
        fgets(msg, strl-1, stream);
        printf("%s", msg);
    }
    fclose(stream);
   return 0;
}


Добавлено через 3 минуты и 53 секунды
char *msg;
где собственно память под это?
возьми файл где строки скажем хотя бы длины так по 100 символов, и это должно будет вылезти.

Автор: Валерия 9.4.2007, 00:00
Тоесть если я просто объявляю
char *var1;

то не резервирую память, и оно может полезть на память скажем, компилятора и зависнуть все нафик?

Добавлено через 6 минут и 36 секунд
...
char *buff;
memset(buff, 0, 256):
...


такое резервирование катит?

Автор: nickless 9.4.2007, 00:09
Валерия, да, память нужно выделять отдельно. 
Не инициализированный указатель указывает неизвестно куда, если попытаться записать туда что-нибудь на память других программ не залезешь (у каждой программы своё адресное пространство), но можно затереть себе что-нибудь (хуже) или схлопотать access violation/segfault (немного лучше)

Цитата(Валерия @  8.4.2007,  23:00 Найти цитируемый пост)
такое резервирование катит? 

Нет, это как раз наглое затирание нулями чего-то.
Память нужно или выделить динамически (malloc в C/new в C++) и не забыть освободить потом (free/delete) или указать адрес существующей переменной, например.
Код

char bla[100];
char * ptr = bla;

Автор: Валерия 9.4.2007, 00:12
Поняла когда побольше заперла туды, выкинуло.
А вот FILE *fp;
такое резервирование тоже получаться не правильное...
Ведь те несколько байт, в которых содержится дескриптор, тоже могут полезть не на то что надо?

Добавлено через 4 минуты и 32 секунды
А вот это написано по всем правилам? (учусь правильно писать).
И будет ли оно везде одинаково работать?
Скажем там под линуксом...
Код

#include <stdio.h>
#include <string.h>
#define SIZE 256

void main()
{
    FILE *fpin, *fpout;
    char *fnamein="D:\\1.txt";
    char *fnameout="D:\\2.txt";
    char buff[SIZE];
    int sz;
    fpin = fopen(fnamein, "r");
    fpout = fopen(fnameout, "w");

    memset(buff, 0, SIZE);

    while (!feof(fpin)){
        fgets(buff, SIZE, fpin);
        sz = strlen(buff)-1;
        if (buff[sz] == '\n'){
            buff[sz] = '\0';
        }

        fputs(buff, fpout);
        printf("%s", buff);
    }

    fclose(fpin);
    fclose(fout);
}

Автор: nickless 9.4.2007, 00:19
С FILE *fp всё нормально, fopen аллокирует память сам, тут нужно по идее только проверять открылся ли файл 
Код

fp = fopen(...);
if (!fp)
{
    // делаем что-нибудь, ошибка при открытии файла
}

Автор: zkv 9.4.2007, 00:23
Цитата(Валерия @  9.4.2007,  00:00 Найти цитируемый пост)
char *buff;
memset(buff, 0, 256):
...
такое резервирование катит? 

нет, не катит,  memset() не выделяет память, а устанавливает в определенное значение. Юзай malloc() или new (в С++).

Цитата(Валерия @  9.4.2007,  00:12 Найти цитируемый пост)
А вот FILE *fp;
такое резервирование тоже получаться не правильное...
Ведь те несколько байт, в которых содержится дескриптор, тоже могут полезть не на то что надо? 

тут другой случай, система открывает заданный файл, а тебе дает его handle, а ты дальше за этот handle им (файлом) управляешь.

Автор: nickless 9.4.2007, 00:35
Цитата(Валерия @  8.4.2007,  23:12 Найти цитируемый пост)
будет ли оно везде одинаково работать?
Скажем там под линуксом

Не будет, в линуксе нет диска D:  smile  Если убрать его, будет
А вообще main должна по стандарту возвращать int, и добавь в конце цикла while 
Код
buff[0] = 0;
, чтоб последняя строка второй раз не записывалась в файл.

Автор: apook 9.4.2007, 04:53
Код

char *msg="V etom sluchae ni hrena ne nado pamjft videljat";

nickless
Код

char bla[]="ABCDEFG";
char *ptr = &bla;

и какой компилятор на это не ругнулся?
тагда уж
Код

char *ptr = &bla[0];

или
Код

char *ptr = bla;

Автор: Валерия 9.4.2007, 13:10
Как ни странно но последняя строка не записалась в файл два раза smile

Добавлено через 2 минуты и 7 секунд
А вот еще такой вопрос.
Если я не делаю free для возврата памяти, и fclose для закрытия файла.
Что в этом будет плохого?
По идее после завершения работы программы она сама всё закроет и высвободит.
Или времени больше на это нужно будет?

Автор: nickless 9.4.2007, 17:12
Цитата(apook @  9.4.2007,  03:53 Найти цитируемый пост)
и какой компилятор на это не ругнулся?

Сорри, & лишнюю написал  smile 

Валерия, 
если не освобождать память в маленькой программе как эта, ничего не будет, но если память выделяется в других функциях или особенно в цикле, а программа расчитана на продолжительную работу, то память может очень быстро кончится smile
Так что освобождать надо всё всегда и везде, чтобы вошло в привычку (исключения только в исключительных случаях).

Цитата(Валерия @  9.4.2007,  12:10 Найти цитируемый пост)
Как ни странно но последняя строка не записалась в файл два раза
А у меня записалась, странно... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)