Разделить строку на C в каждом пробеле

Я хочу написать программу на C, которая отображает каждое слово целого предложения (взятого как ввод) на отдельной строке. Это то, что я сделал до сих пор:


void manipulate(char *buffer); int get_words(char *buffer); int main(){ char buff[100]; printf("sizeof %d\nstrlen %d\n", sizeof(buff), strlen(buff)); // Debugging reasons bzero(buff, sizeof(buff)); printf("Give me the text:\n"); fgets(buff, sizeof(buff), stdin); manipulate(buff); return 0; } int get_words(char *buffer){ // Function that gets the word count, by counting the spaces. int count; int wordcount = 0; char ch; for (count = 0; count < strlen(buffer); count ++){ ch = buffer[count]; if((isblank(ch)) || (buffer[count] == '\0')){ // if the character is blank, or null byte add 1 to the wordcounter wordcount += 1; } } printf("%d\n\n", wordcount); return wordcount; } void manipulate(char *buffer){ int words = get_words(buffer); char *newbuff[words]; char *ptr; int count = 0; int count2 = 0; char ch = '\n'; ptr = buffer; bzero(newbuff, sizeof(newbuff)); for (count = 0; count < 100; count ++){ ch = buffer[count]; if (isblank(ch) || buffer[count] == '\0'){ buffer[count] = '\0'; if((newbuff[count2] = (char *)malloc(strlen(buffer))) == NULL) { printf("MALLOC ERROR!\n"); exit(-1); } strcpy(newbuff[count2], ptr); printf("\n%s\n",newbuff[count2]); ptr = &buffer[count + 1]; count2 ++; } } } 

Хотя выход – это то, что я хочу, у меня действительно много черных пространств после последнего отображаемого слова, а malloc () возвращает NULL, поэтому ОШИБКА MALLOC! отображается в конце. Я могу понять, что ошибка в моей реализации malloc (), но я не знаю, что это такое.

Есть ли еще более элегантный – как правило, лучший способ сделать это?

Заранее спасибо.

http://www.cplusplus.com/reference/clibrary/cstring/strtok/

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

С веб-сайта:

 char * strtok ( char * str, const char * delimiters ); 

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

Как только завершающий нулевой символ str находится в вызове strtok, все последующие вызовы этой функции (с нулевым указателем в качестве первого аргумента) возвращают нулевой указатель.

параметры

  • ул
    • Строка C для усечения.
    • Обратите внимание, что эта строка модифицируется путем разбиения на более мелкие строки (токены). Alternativelly [sic] может быть указан нулевой указатель, и в этом случае функция продолжает сканирование, где предыдущий успешный вызов функции завершился.
  • разделители
    • Строка C, содержащая символы разделителя.
    • Они могут варьироваться от одного вызова к другому.

Возвращаемое значение

Указатель на последний токен, найденный в строке. Возвращает нулевой указатель, если для возврата нет токенов.

пример

 /* strtok example */ #include  #include  int main () { char str[] ="- This, a sample string."; char * pch; printf ("Splitting string \"%s\" into tokens:\n",str); pch = strtok (str," ,.-"); while (pch != NULL) { printf ("%s\n",pch); pch = strtok (NULL, " ,.-"); } return 0; } 

Для удовольствия это реализация, основанная на обратном вызове:

 const char* find(const char* s, const char* e, int (*pred)(char)) { while( s != e && !pred(*s) ) ++s; return s; } void split_on_ws(const char* s, const char* e, void (*callback)(const char*, const char*)) { const char* p = s; while( s != e ) { s = find(s, e, isspace); callback(p, s); p = s = find(s, e, isnotspace); } } void handle_word(const char* s, const char* e) { // handle the word that starts at s and ends at e } int main() { split_on_ws(some_str, some_str + strlen(some_str), handle_word); } 

malloc(0) может (необязательно) возвращать NULL , в зависимости от реализации. Вы понимаете, почему вы можете называть malloc(0) ? Или, точнее, вы видите, где вы читаете и пишете размер вашего массива?

Рассмотрим использование strtok_r , как предложили другие, или что-то вроде:

 void printWords(const char *string) { // Make a local copy of the string that we can manipulate. char * const copy = strdup(string); char *space = copy; // Find the next space in the string, and replace it with a newline. while (space = strchr(space,' ')) *space = '\n'; // There are no more spaces in the string; print out our modified copy. printf("%s\n", copy); // Free our local copy free(copy); } 

Что-то не так: get_words() всегда возвращает меньше, чем фактическое количество слов, поэтому в итоге вы get_words() :

 char *newbuff[words]; /* Words is one less than the actual number, so this is declared to be too small. */ newbuff[count2] = (char *)malloc(strlen(buffer)) 

count2 , в конце концов, всегда больше, чем количество элементов, которые вы объявили для newbuff[] . Почему malloc() не возвращает действительный ptr, хотя, я не знаю.

Вы должны быть malloc’ing strlen (ptr), а не strlen (buf). Кроме того, ваш count2 должен быть ограничен числом слов. Когда вы дойдете до конца строки, вы продолжаете перебирать нули в своем буфере и добавляете нулевые строки в свой массив.

Так же, как идея другого стиля манипуляции строками в C, вот пример, который не изменяет исходную строку и не использует malloc . Чтобы найти пробелы, я использую функцию libc strpbrk .

 int print_words(const char *string, FILE *f) { static const char space_characters[] = " \t"; const char *next_space; // Find the next space in the string // while ((next_space = strpbrk(string, space_characters))) { const char *p; // If there are non-space characters between what we found // and what we started from, print them. // if (next_space != string) { for (p=string; p 
 char arr[50]; gets(arr); int c=0,i,l; l=strlen(arr); for(i=0;i 
  • «плавающая» и «двойная» точность
  • Попробовать команды catch в C
  • Почему getchar () не распознает return как EOF на консоли?
  • Переменные стека против переменных кучи
  • Эта программа звучит колокол!
  • Отключение политики одного и того же происхождения в Safari
  • Поймать Ctrl-C в C
  • Что возвращает sizeof (имя функции)?
  • Почему FILE * не сохраняет адрес открытого файла
  • Представление целых чисел в двухместных
  • Альтернативный (K & R) C синтаксис для объявления функции против прототипов
  • Interesting Posts

    Является ли instanceof плохой практикой? Если да, то при каких обстоятельствах это еще предпочтительнее?

    Как подключиться к базе данных JDBC / источнику данных в приложении на основе сервлета?

    Как я могу получить список каталогов ресурсов из моего приложения для Android?

    Плохая практика использования собственных Java-classов Sun?

    Каковы правила автоматического разыменования Rust?

    Точная ошибка с поплавками в Java

    Как получить таблицу непредвиденных расходов?

    Исключение начального фильтра struts2 – попытался добавить JAR, но тот же результат

    Почему fmt.Println внутри goroutine не печатает строку?

    Преобразовать шестнадцатеричную строку в целое число эффективно в C?

    Как создать контекст рендеринга OpenGL с прозрачным фоном?

    Каковы допустимые символы в субдомене?

    Как найти последнюю строку, содержащую данные на листе Excel с макросом?

    Как создать комбинации нескольких векторов без контуров жесткого кодирования в C ++?

    Как сделать целое число log2 () в C ++?

    Давайте будем гением компьютера.