Программа должна считывать строки из файла, в строке данные разделены пробелами (только после первого данного идет 3 пробела). программа должна сохранять данные в переменные... Вот что у мя получилось...
компилится, но либо вылетает, либо уходит в бесконечный цикл... уже 3й день парюсь над ней... как поправить не знаю... ПОМОГИТЕ ПЛИЗ! Пишу на Си
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{ FILE * pFile;
int c_count;
char * string ; // обрабатываемая строка
char * p1, * p2, * p3, * p4, * p5, * p6, * p7, * p8, * p9, * p10;
char * pch;
pFile = fopen ("access.log.1" , "r");
if (pFile == NULL) perror ("Error opening file");
else while ( !feof(pFile) )
{ c_count=1;
fgets(string ,255,pFile);
puts(string);
pch=strchr(string,' ');
while (pch!=NULL)
{pch=strchr(pch+1,' ');
switch(c_count)
{
case 1: strncpy(p1,string,pch-string+4);
case 2: strncpy(p2,string,pch-string+1);
case 3: strncpy(p3,string,pch-string+1);
case 4: strncpy(p4,string,pch-string+1);
case 5: strncpy(p5,string,pch-string+1);
case 6: strncpy(p6,string,pch-string+1);
case 7: strncpy(p7,string,pch-string+1);
case 8: strncpy(p8,string,pch-string+1);
case 9: strncpy(p9,string,pch-string+1);
case 10: strncpy(p10,string,pch-string+1); }
if (strchr(string,' ')) c_count++;
}
fclose(pFile);
}
//printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",p1,p2,p3,p4,p5,p6,p7,p8,p9,p10);
system("PAUSE");
return 0;
}
Скажите в чем моя ошибка! (работа со строками)
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Ты определил миллион указателей на char, но я нигде не вижу где выделяется память под строку, в которую ты собираешься считывать данные.
Выделять память можно двумя способабами: динамически и статически.
Динамичечкое выделение подразумевает использование парных функций malloc и free в случае С и парных операторов new и delete в случае С++. В случае динамического выделения память резервируется в так называемой heap области памяти. Её ещё называют динамической областью.
Стачиское выделение подразумевает использование синтаксической конструкции char pszBudder[ELEMENTS_NUMBER], где ELEMENTS_NUMBER - константа, указывающая на количество резервируемых элементов (синтаксис одинаков для С и С++). В этом случае память выделяется либо в сегменте данных, если декларация помещена вне функций, либо на стеке, если декларация помещена внутри функции (или метода для С++).
В твоём случае память должны быть выделена под все указатели на char твоей программы, исключая pch. Однако программу можно подифицировать так, чтобы память выделялась только под string, а все остальные поинтеры просто указывали на какой либо элемент этого массива. Для этого вместо вызова strncpy нужно использовать присвоение, а в конце слова на месте пробела ставить символ '\0', чтобы функция printf "думала", что на этом слово и заканчивается.
Выделять память можно двумя способабами: динамически и статически.
Динамичечкое выделение подразумевает использование парных функций malloc и free в случае С и парных операторов new и delete в случае С++. В случае динамического выделения память резервируется в так называемой heap области памяти. Её ещё называют динамической областью.
Стачиское выделение подразумевает использование синтаксической конструкции char pszBudder[ELEMENTS_NUMBER], где ELEMENTS_NUMBER - константа, указывающая на количество резервируемых элементов (синтаксис одинаков для С и С++). В этом случае память выделяется либо в сегменте данных, если декларация помещена вне функций, либо на стеке, если декларация помещена внутри функции (или метода для С++).
В твоём случае память должны быть выделена под все указатели на char твоей программы, исключая pch. Однако программу можно подифицировать так, чтобы память выделялась только под string, а все остальные поинтеры просто указывали на какой либо элемент этого массива. Для этого вместо вызова strncpy нужно использовать присвоение, а в конце слова на месте пробела ставить символ '\0', чтобы функция printf "думала", что на этом слово и заканчивается.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Cпасибо! Исправил уже! Если интересно как могу выложить код! =)Romeo писал(а):Ты определил миллион указателей на char, но я нигде не вижу где выделяется память под строку, в которую ты собираешься считывать данные.
Выделять память можно двумя способабами: динамически и статически.
Динамичечкое выделение подразумевает использование парных функций malloc и free в случае С и парных операторов new и delete в случае С++. В случае динамического выделения память резервируется в так называемой heap области памяти. Её ещё называют динамической областью.
Стачиское выделение подразумевает использование синтаксической конструкции char pszBudder[ELEMENTS_NUMBER], где ELEMENTS_NUMBER - константа, указывающая на количество резервируемых элементов (Синтаксис одинаков для С и С++). В этом случае память выделяется либо в сегменте данных, если декларация помещена вне функций, либо на стеке, если декларация помещена внутри функции (либо метода для С++).
В твоём случае память должны быть выделена под все указатели на char твоей программы, исключая pch. Однако программу можно подифицировать так, чтобы память выделялась только под string, а все остальные поинтеры просто указывали на какой либо элемент этого массива. Для этого вместо вызова strncpy нужно использовать присвоение, а в конце слова на месте пробела ставить символ '\0', чтобы функция printf "думала", что на этом слово и заканчивается.
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Выложи. Это будет полезно читателям. Заодно я покритикую, если ты вне против
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
не против пожалуйтса критикуйте и разносите меня в пух и прах! =)))Romeo писал(а):Выложи. Это будет полезно читателям. Заодно я покритикую, если ты вне против
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{ FILE * pFile;
int c_count;
char * str ; // обрабатываемая строка
char pch[]=" ";
char *word;
char *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10;
int i; //счетчик
pFile = fopen ("access.log.0" , "r");
if (pFile == NULL) perror ("Error opening file");
else
while ( !feof(pFile) )
{ i=1;
fgets(str ,255,pFile);
puts(str);
printf("\n");
}
word=strtok(str,pch);
while(word!=NULL)
printf("%s\n",word);
{ switch (i)
{case 1: p1=word;
case 2: p2=word;
case 3: p3=word;
case 4: p4=word;
case 5: p5=word;
case 6: p6=word;
case 7: p7=word;
case 8: p8=word;
case 9: p9=word;
case 10: p10=word; }
i++;
word=strtok(NULL,pch);
}
fclose(pFile);
printf("%s\n","MEDBED ");
system("PAUSE");
return 0;
}
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Не верю, что работает. Ты так и не послушался меня и не выделил память под str. Если работает, то тебе просто очень повезло. Значит в str по чистой случайности попало значение адреса из сегмента данных в который можно писать. В релиз сборке, где все указатели автоматически инициализируются NULL, работать точно не будет. Замени char * str на char char str[256].
Ещё один коментарий. Подождать нажатия клавиши можно значительно проще, чем вызываю функцию системы (в данном случае DOS). Достаточно вызвать getch();. Он находится в хеадере conio.h.
Если лень вызывать подключать ещё один хеадер, могу найчить как это сделать на ассемблере
Кстати, если не будешь использовать вызов system, то от включения stdlib.h можно будет отказаться. Опять-таки экономим на размере исполняемого файла.
Ещё один коментарий. Подождать нажатия клавиши можно значительно проще, чем вызываю функцию системы (в данном случае DOS). Достаточно вызвать getch();. Он находится в хеадере conio.h.
Если лень вызывать подключать ещё один хеадер, могу найчить как это сделать на ассемблере
Код: Выделить всё
asm{
xor ax, ax
int 16h
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.