我正在尝试读取诸如“ls -la /tmp”之类的命令行,并且需要将它们拆分为字符指针数组。我使用 getline() 读取输入,并将输入和指针数组传递给函数,“i”返回命令/参数的数量,因此在本例中为 3。我希望能够忽略/删除任何空格而不是 seg空行上的错误,例如充满制表符的行,因此每个数组索引将分别指向“ls”,“-la”,“/tmp”。非常感谢任何帮助。
int string_split(char * input, char * commands[]) {
int i = 0;
const char * delim = " \t\r\n\a";
//Remove trailing newline character
input[strcspn(input, "\n")] = '\0';
//Break user input into each command using fixed delimiter
while((commands[i] = strsep(&input, delim)) != NULL) {
//Each break counted then returned to reference number of command/arguments
i++;
}
return i;
}
更喜欢使用 strsep 而不是 strtok/strtok_r,我已经尝试过这两种方法并不断遇到段错误。
您可以轻松地自己创建这样的功能。
/**
* @brief Splits a string into substrings using a delimiter.
*
* This function splits the input string `str` into substrings based on the provided
* delimiter string `delim`, and stores pointers to these substrings in the `argv`
* array. The maximum number of substrings to store is specified by `argvsize`.
*
* @param argv [out] An array of pointers to store the substrings.
* @param argvsize [in] The size of the `argv` array.
* @param str [in,out] The input string to split. Will be modified during processing.
* @param delim [in] The delimiter string used to split the input string.
* @return The number of substrings stored in the `argv` array.
*
* @details This function modifies the input string by replacing delimiter characters
* with null terminators to separate substrings. The `argv` array is populated with
* pointers to the start of each substring. If there are more substrings than the
* size of the `argv` array, only the first `argvsize` substrings will be stored.
*
* @note The input string `str` will be modified during processing.
*
* \code{c}
* char input[] = "apple,orange,banana,grape";
* char *substrings[4];
* size_t num_substrings = ASCII_splitstring(substrings, 4, input, ",");
* for (size_t i = 0; i < num_substrings; ++i) {
* printf("Substring %zu: %s", i, substrings[i]);
* }
*
* // Output:
* // Substring 0: apple
* // Substring 1: orange
* // Substring 2: banana
* // Substring 3: grape
* \endcode
*
* @see strchr
*/
size_t ASCII_splitstring(char **argv, size_t argvsize, char *str, const char *delim)
{
size_t pos = 0;
if(argv && argvsize && str && *str)
{
memset(argv, 0, argvsize * sizeof(*argv));
argv[pos++] = str;
while(*str)
{
if(strchr(delim, *str))
{
*str++ = 0;
argv[pos++] = str;
if(pos >= argvsize) break;
}
else
{
str++;
}
}
}
return pos;
}