LINUX.ORG.RU

интерсно


0

0

интересно, почему нижеследующий код работает в винде, но не работает в linux'е?

//------------------------------------------------------------------
#include <stdio.h>

int main()
{
char c;
FILE *f;
FILE *fp;

f = fopen("out", "w");
fp = fopen("main", "r");


while ( (c = getc(fp)) != EOF) {

if (c == '\n') {

c = getc(fp);

if (c == '\n') ;
else {
fputc ('\n', f);
fputc (c, f);
}

}
else fputc(c, f);

}




}

anonymous

У меня работает (gcc 3.4.5)

anonymous
()

Что значит "не работает"? В кору дампицо или чо?

А так, я бы предположил, что надо учитывать тот факт, что разврат коредки и перевот страки в виндовсе и никсе несколько различаюццо.

anonymous
()

WORKSFORME (gcc 4.2.1)

может return 0; и fcloseall(); в конце нужно поставить?

generatorglukoff ★★
()
Ответ на: комментарий от anonymous

Не, не помогло закрыть. Самое интересное, что походу дело в файле.
То что, любой созданный в linux'е файл работает.
А я пробую файл из винды. Мож от того?

anonymous
()
Ответ на: комментарий от anonymous

Поставь проверку дескрипторов, вдруг пишешь в пустоту?

if (f==NULL || fp==NULL) { puts("error"); exit(1); }

anonymous
()
Ответ на: комментарий от anonymous

Попробуй заменить обе проверки
if (c == '\n')
на
if ((c == '\n')||(c == '\r'))

anonymous
()

char c;

должно быть
int c;

если вы используте getc,
т.к. не факт что EOF влезает в char

fghj ★★★★★
()

>почему нижеследующий код работает в винде, но не работает в linux'е?

Ты б хоть объяснил, что значит "не работает" -- телепаты в отпуске.

Вообще косяк вероятно в следующем: в винде, если открыть файл в "текстовом" режиме (у тебя именно так), при чтении последовательность \r\n автоматически транслируются в единичный символ \n; при записи происходит обратная трансляция.

Напомню, что стандартный виндовый перевод строки -- это именно пара байт \r\n, а не один \n, как в *nix.

Чтобы открыть файл в "двоичном" режиме под виндой, fopen надо указывать "rb" (чтение) или "wb" (запись).

Под *nix такой хрени нет, да и вообще отсутвует дифференциация на "текстовый" и "двоичный" режим чтения/записи файлов.

tche
()
Ответ на: комментарий от tche

> Под *nix такой хрени нет, да и вообще отсутвует дифференциация на "текстовый" и "двоичный" режим чтения/записи файлов

Да? Разве это не *никсовы уши как раз?

anonymous
()
Ответ на: комментарий от tche

Я про двоичный и символьный режимы чтения файла, а не про разврат каредки грю ;-)

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

anonymous
()
Ответ на: комментарий от tche

>>Напомню, что стандартный виндовый перевод строки -- это именно пара байт \r\n, а не один \n, как в *nix.

В этом случае разве не наоборот будет? Ведь я проверяю на '\n', а не \r\n. Или виндовый компилер преобразует проверку '\n' на \r\n?

Я выше написал как не работает. out == main

anonymous
()
Ответ на: комментарий от anonymous

Да, в этом причина! НО теперь надо немножечко поразмыслить. Потому что теперь ненужная пустая строка равна \r\n\r\n. Т.е. вдвое длинее. Хотя уже есть идейка. В любом случае, всем спасибо, узнал новое. ;-)

anonymous
()
Ответ на: комментарий от anonymous

fpos(), тока незачем. Насколько я понимаю твою задачу, проще что-то типа такого сделать:

#include <stdio.h> int main() { char c; FILE *f; FILE *fp; f = fopen("out", "w"); fp = fopen("main", "r"); while ( (c = getc(fp)) != EOF) { if ((c == '\n')||(c == '\r')) { while((c == '\n')||(c == '\r')) c = getc(fp); //вычитываем все "концы" if (c != EOF){ // пока вычитывали, файл мог закончиться fputc ('\n', f); fputc (c, f); } } else fputc(c, f); } }

или:

... int state=0;

while ( (c = getc(fp)) != EOF) { if ((c == '\n')||(c == '\r')) state=1; else{ if(state==0) fputc ('\n', f); fputc (c, f); } }

anonymous
()
Ответ на: комментарий от anonymous

fpos(),
тока незачем. Насколько я понимаю твою задачу, проще что-то типа такого сделать:


#include <stdio.h>

int main()
{
char c;
FILE *f;
FILE *fp;

f = fopen("out", "w");
fp = fopen("main", "r");


while ( (c = getc(fp)) != EOF) {
if ((c == '\n')||(c == '\r')) {
while((c == '\n')||(c == '\r')) c = getc(fp); //вычитываем все "концы"
if (c != EOF){ // пока вычитывали, файл мог закончиться
fputc ('\n', f);
fputc (c, f);
}
}
else fputc(c, f);

}
}




или:

...
int state=0;

while ( (c = getc(fp)) != EOF) {
if ((c == '\n')||(c == '\r')) state=1;
else{
if(state==0) fputc ('\n', f);
fputc (c, f);
}
}



PS Пардон, опять формат забыл выставить..

anonymous
()
Ответ на: комментарий от anonymous

Ошибся: не if(state==0) fputc ('\n', f); а if(state==1) fputc ('\n', f);

разумеется.

anonymous
()
Ответ на: комментарий от anonymous

Да ну. Это не катит. Удалить все новые строки. Будет одна строка.

Можно сделать со второй переменной.

anonymous
()
Ответ на: комментарий от anonymous

> Я про первый вариант

Ну так там же изредка вставляется \n :-)

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

anonymous
()
Ответ на: комментарий от anonymous

Нет, нет и нет. Как я сразу сказал!. Эти оба варианта не катят. Даже объяснять не хочу.

>>Не будет, см.внимательнее ;-) Прально, не будет, будет на каждой строкe один символ ;-).

anonymous
()
Ответ на: комментарий от anonymous

Блин, я попробовал запустить эту программу под линнахом и у меня сломался компьютер, и во всём доме погас свет!!! %-о

anonymous
()
Ответ на: комментарий от anonymous

Вот, только надо доработать.


while ( (cp = getc(fp) != EOF) {

c = getc(fp);

if ( c == '\n' && cp == '\r') ;

else {
fputc(cp,f);
fputc(c,f);

}

anonymous
()
Ответ на: комментарий от anonymous

> if ( c == '\n' && cp == '\r') ;

Не надо так дорабатывать: во-первых непонятно где инициализируется "с", а во-вторых подразумевается жесткая привязка к последовательности символов в конце строки.

anonymous
()
Ответ на: комментарий от anonymous

Знаю насчёт привязки. Это на скорую руку. Если строку имеет нечетное кол-во символов - не сработает.

А почему не понятно где "C" инициализируется?

anonymous
()
Ответ на: комментарий от anonymous

> А почему не понятно где "C" инициализируется?

Потому, что я моргнул, когда добежал глазом до этой строчки :-)

anonymous
()

Для начала хорошо бы было сформулировать задачу по русски

Плюс к тому, что уже сказано нет проверки на конец файла при втором fgetc

Не надо добавлять проверку на '\r' - Преобразовывать текстовые файлы при копирование - задача того, кто их копирует.

ival ★★
()
Ответ на: комментарий от ival

О! Почти сделал.
Задача проста - убрать пустые строки.

Вот код, смотрите.

while ( (c = getc(fp)) != EOF) {

if (c == '\n')

while ( (c = getc(fp)) == '\r' ) ;


else fputc(c, f);

}

anonymous
()
Ответ на: комментарий от ival

> Не надо добавлять проверку на '\r' - Преобразовывать текстовые файлы при копирование - задача того, кто их копирует.

Вот из-за такого подхода пользователи и предпочитают работать с виндовсом :-)

Зачем делать неуниверсально там, где ничего не стоит сделать универсально?

Товарищи, запомните этого человека с ником "ival" - он пытается учить вас плохому!

anonymous
()
Ответ на: комментарий от anonymous

>и как это отработает последовательность \n\r\n\r\n\r ?

Откуда такая последовательность?
У нас \r\n\r\n\r\n\r\n

Её она обработает так что останется только один \r\n!!

anonymous
()
Ответ на: комментарий от anonymous

> У нас \r\n\r\n\r\n\r\n

Сгодня такая, завтра этакая, а послезавтра ваще \n\n\n\n.

> Её она обработает так что останется только один \r\n!!

И \n останется?

anonymous
()
Ответ на: комментарий от tche

>>Что если строки не совсем пустые -- содержат пробелы и/или символы табуляции?

Остаются )))))

anonymous
()
Ответ на: комментарий от anonymous

А если этим бинарник провернуть и потом запустить? :-)

anonymous
()
Ответ на: комментарий от anonymous

>Зачем делать неуниверсально там, где ничего не стоит сделать универсально?

По русски это называется некорректный ввод. Вот из за таких виндузяднегов в html бардак.

ival ★★
()
Ответ на: комментарий от ival

> По русски это называется некорректный ввод. Вот из за таких виндузяднегов в html бардак.

Одной программе это некорретный ввод, другая же вместо того, что бы учить пользователя корректности, продолжает работать исправно. Какую выберет пользователь? И нахрена вообще грузить пользователя ограничениями там, где они в принципе безразличны? Так поступают только идиоты!

anonymous
()
Ответ на: комментарий от anonymous

>Одной программе это некорретный ввод, другая же вместо того, что бы учить пользователя корректности, продолжает работать исправно. Какую выберет пользователь?

Ну у нас пока большинство выберает винду:)

>И нахрена вообще грузить пользователя ограничениями там, где они в принципе безразличны? Так поступают только идиоты!

Вот запустит он эту прогу под линукс, она все \r съест. Потом закачает результат как есть в windows, а там раз - и весь файл в блокноте в одну строчку с квадратиками вместо переноса строк. На какую ось будет пользователь матерится? Сохранять исходный формат?? А что делать если разрывы строк где \n\r - где \n, где \r, и понять к какой системе относится файл проблематично? В итоге получится куча трудно формализуемых эвристик (для такой простой задачи!). Я бы предпочел, что бы программы ругались на некорректный ввод и учили пользователей материться на программы/программистов, которые генерят некорректный вывод.

ival ★★
()
Ответ на: комментарий от ival

> там раз - и весь файл в блокноте в одну строчку с квадратиками вместо переноса строк

Нотепёд-то как раз юниксовы концы съест и не подавится, а вот какой-нибудь vi в консоли будет показывать ^M на виндозные концы. Потому что сделано такими же как вы маргиналами :-)

anonymous
()
Ответ на: комментарий от ival

>>Вот запустит он эту прогу под линукс, она все \r съест. Потом закачает результат как есть в windows, а там раз - и весь файл в блокноте в одну строчку с квадратиками вместо переноса строк. На какую ось будет пользователь матерится? Сохранять исходный формат?? А что делать если разрывы строк где \n\r - где \n, где \r, и понять к какой системе относится файл проблематично? В итоге получится куча трудно формализуемых эвристик (для такой простой задачи!). Я бы предпочел, что бы программы ругались на некорректный ввод и учили пользователей материться на программы/программистов, которые генерят некорректный вывод.

Не понял. Это щас на меня что-то было

anonymous
()
Ответ на: комментарий от ival

>>Вот запустит он эту прогу под линукс, она все \r съест. Потом закачает результат как есть в windows, а там раз - и весь файл в блокноте в одну строчку с квадратиками вместо переноса строк. На какую ось будет пользователь матерится? Сохранять исходный формат?? А что делать если разрывы строк где \n\r - где \n, где \r, и понять к какой системе относится файл проблематично? В итоге получится куча трудно формализуемых эвристик (для такой простой задачи!). Я бы предпочел, что бы программы ругались на некорректный ввод и учили пользователей материться на программы/программистов, которые генерят некорректный вывод.

И с чего мне на windows строиться? А ? ОТВЕТЬ?

anonymous
()
Ответ на: комментарий от anonymous

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

Я бы предпочел тебе язык оторвать, за такие слова.

anonymous
()
Ответ на: комментарий от anonymous

>Нотепёд-то как раз юниксовы концы съест и не подавится,

Я на эти грабли с текстовыми файлами с notepadом как то наступал.

>а вот какой-нибудь vi в консоли будет показывать ^M на виндозные концы. Потому что сделано такими же как вы маргиналами :-)

а vim как раз умеет вроде бы с этим бороться (help fileformats)

ival ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.