Глядя на другие ответы, для новичка в C это выглядело бы сложным из-за небольшого размера кода, я подумал, что я бы вставил это для новичка, возможно, было бы проще фактически проанализировать строку вместо использования strtok
... как то так:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char **parseInput(const char *str, int *nLen);
void resizeptr(char ***, int nLen);
int main(int argc, char **argv){
int maxLen = 0;
int i = 0;
char **ptr = NULL;
char *str = "valgrind --leak-check=yes --track-origins=yes ./a.out";
ptr = parseInput(str, &maxLen);
if (!ptr) printf("Error!\n");
else{
for (i = 0; i < maxLen; i++) printf("%s\n", ptr[i]);
}
for (i = 0; i < maxLen; i++) free(ptr[i]);
free(ptr);
return 0;
}
char **parseInput(const char *str, int *Index){
char **pStr = NULL;
char *ptr = (char *)str;
int charPos = 0, indx = 0;
while (ptr++ && *ptr){
if (!isspace(*ptr) && *ptr) charPos++;
else{
resizeptr(&ptr, ++indx);
pStr[indx-1] = (char *)malloc(((charPos+1) * sizeof(char))+1);
if (!pStr[indx-1]) return NULL;
strncpy(pStr[indx-1], ptr - (charPos+1), charPos+1);
pStr[indx-1][charPos+1]='\0';
charPos = 0;
}
}
if (charPos > 0){
resizeptr(&pStr, ++indx);
pStr[indx-1] = (char *)malloc(((charPos+1) * sizeof(char))+1);
if (!pStr[indx-1]) return NULL;
strncpy(pStr[indx-1], ptr - (charPos+1), charPos+1);
pStr[indx-1][charPos+1]='\0';
}
*Index = indx;
return (char **)pStr;
}
void resizeptr(char ***ptr, int nLen){
if (*(ptr) == (char **)NULL){
*(ptr) = (char **)malloc(nLen * sizeof(char*));
if (!*(ptr)) perror("error!");
}else{
char **tmp = (char **)realloc(*(ptr),nLen);
if (!tmp) perror("error!");
*(ptr) = tmp;
}
}
Я немного изменил код, чтобы сделать его проще. Единственная строковая функция, которую я использовал, была strncpy
.. конечно, она немного затянута, но она динамически перераспределяет массив строк вместо использования жестко закодированного MAX_ARGS, что означает, что двойной указатель уже перегружает память когда только 3 или 4 будет делать, что также сделало бы использование памяти эффективным и крошечным, используя realloc
, простой синтаксический анализ покрывается использованием isspace
, поскольку он выполняет итерацию с использованием указателя. Когда встречается пробел, он realloc
съедает двойной указатель и malloc
смещение для хранения строки.
Обратите внимание, как тройные указатели используются в функции resizeptr
. На самом деле, я подумал, что это послужит отличным примером простой программы на C, указателей, realloc, malloc, передачи по ссылке, базового элемента парсинг строки ...
Надеюсь, это поможет,
С наилучшими пожеланиями,
Том.