Разделить строку на 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 (), но я не знаю, что это такое.
Есть ли еще более элегантный – как правило, лучший способ сделать это?
- Декодирование и проверка токена JWT с использованием System.IdentityModel.Tokens.Jwt
- Правильный способ утилиты Image / Bitmap и PictureBox
- Функция scanf getchar пропускается
- хранение денежных сумм в mysql
- Как массив хранится в памяти?
Заранее спасибо.
- Что такое определения, декларации и назначения C ++?
- Использование нулевого оператора в C
- Присвоение строк массивам символов
- плавать до неожиданного поведения
- вызов main () в main () в c
- Почему «memset (arr, -1, sizeof (arr) / sizeof (int))« не очищает целочисленный массив до -1?
- Как правильно использовать ключевое слово extern в C
- Какие операции и функции на +0.0 и -0.0 дают разные арифметические результаты?
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