拆分字符串并返回数组的C代码?

t3psigkw  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(116)

我已经有一段时间没有使用C了,我正在尝试编写一个简单的实用程序,它接受一个输入字符串并返回一个字符串数组。

draw 1 2 3

输出数组为:

out[0] = draw
out[1] = 1
out[2] = 2
out[3] = 3

我感谢和所有的帮助,请善良,我最近主要使用C#,它有一个非常好的字符串。分裂函数!
下面是我尝试过的,找到了一些示例代码,并试图修改它。

#include<stdio.h>
#include <string.h>

char outPut[50][50] splitString(char str[200])
{
  int iCount = 1;
  // Returns first token
  char* token = strtok(str, " ");
  outArray[0] = token;
  
  // Keep printing tokens while one of the
  // delimiters present in str[].
  while (token != NULL) 
  {
    printf("%s\n", token);
    token = strtok(NULL, " ");
    outArray[iCount] = token;
    iCount++;
  }
    
}
int main ()
{
  char str[200];
  char outArr[50][50];
  puts ("Enter text:");
  gets(str);
  outArr = splitString(str);
  for (int i=0; i<outArr.length; i++)
  {
     printf(Array element %d is %s", i, outArr[i]);       
  }
  return 0;
}
dgtucam1

dgtucam11#

如何从函数返回数组

在C语言中,不能直接返回数组。函数main必须告诉函数splitString它应该写入的数组地址。因此,您应该将函数splitString的参数更改为:

int splitString( char input[200], char output[50][50] )

由于数组不能作为函数参数传递,因此两个数组参数都将decay指向指向数组第一个元素的指针。对于二维数组,参数将衰减为指向外部数组第一个元素的指针。
我把返回类型改为int,因为函数splitStrings必须告诉函数main它找到了多少个token并写入数组,所以函数splitStrings返回这个数字是有意义的。
现在可以从函数main调用函数splitString,如下所示

num_tokens = splitString( str, outArr );

相当于

num_tokens = splitString( &str[0], &outArr[0] );

因为数组衰减为指向其第一个元素的指针。

如何复制字串

在C中,不能复制如下字符串:

outArray[iCount] = token;

实际上,你告诉编译器要做的是复制指针token(而不是它所指向的字符串)并将其赋值给数组。这是行不通的,因为你不能给数组本身赋值。你只能给数组中的各个元素赋值。
如果要复制指针指向的字符串而不是指针本身,则应使用函数strcpy,如下所示:

strcpy( outArray[iCount], token );

由于数组到指针的衰减,此函数调用等效于:

strcpy( &outArray[iCount][0], token );

但是,由于目标数组只有49字符加上终止空字符的空间,因此您应该首先验证标记是否太长,否则可能会导致buffer overflow,这可能会导致程序崩溃或以其他方式出现错误行为。

是否使用函数gets

函数gets非常危险,因此已从ISO C标准中删除,因为没有办法防止缓冲区溢出,除非输入来自受信任的来源。因此,您应该停止使用此函数,而改用fgets。有关详细信息,请参阅以下问题:
Why is the gets function so dangerous that it should not be used?
请注意,如果您使用fgets而不是gets,则通常会在输入的末尾有一个换行符。您通常会希望删除它。请参阅以下问题了解如何删除它:
Removing trailing newline character from fgets() input

固定代码

在应用了上面提到的所有修复程序,并应用了一些其他的小改进之后,您的代码应该如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_TOKENS 50
#define MAX_TOKEN_LENGTH 50

int splitString( char input[], char output[MAX_TOKENS][MAX_TOKEN_LENGTH] )
{
    //this variable will keep track of the number of found tokens
    int num_tokens = 0;

    //find first token
    char* token = strtok( input, " " );

    while ( token != NULL )
    {
        //verify that array is large enough to store this many tokens
        if ( num_tokens == MAX_TOKENS )
        {
            fprintf( stderr, "Too many tokens to fit in array!\n" );
            exit( EXIT_FAILURE );
        }

        //verify that token length is not too long to fit in buffer
        if ( strlen( token ) >= MAX_TOKEN_LENGTH )
        {
            fprintf( stderr, "Error: Token length too long to fit in buffer!\n" );
            exit( EXIT_FAILURE );
        }

        //print the token for debugging purposes
        printf( "Adding token to array: %s\n", token );

        //copy the token to the output buffer
        strcpy( output[num_tokens], token );

        //increment the number of found tokens
        num_tokens++;

        //attempt to find next token for next loop iteration
        token = strtok( NULL, " " );
    }

    //return the number of tokens found to the calling function
    return num_tokens;
}

int main( void )
{
    char line[200];
    char outArr[MAX_TOKENS][MAX_TOKEN_LENGTH];
    char *p;
    int num_tokens;

    //prompt user for input
    printf( "Enter text: ");

    //attempt to read one line of input
    if ( fgets( line, sizeof line, stdin ) == NULL )
    {
        fprintf( stderr, "Input error!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to find newline character in input
    p = strchr( line, '\n' );

    //verify that input line was not too long to fit in buffer
    if ( p == NULL && !feof( stdin ) )
    {
        fprintf( stderr, "Input was too long for input buffer!\n" );
        exit( EXIT_FAILURE );
    }

    //remove newline character from input by overwriting it with
    //a null terminating character
    if ( p != NULL )
    {
        *p = '\0';
    }

    //perform the function call
    num_tokens = splitString( line, outArr );

    //output the result of the function call
    for ( int i = 0; i < num_tokens; i++ )
    {
        printf( "Array element %d is %s.\n", i, outArr[i]); 
    }

    return EXIT_SUCCESS;
}

此程序具有以下行为:

Enter text: draw 1 2 3
Adding token to array: draw
Adding token to array: 1
Adding token to array: 2
Adding token to array: 3
Array element 0 is draw.
Array element 1 is 1.
Array element 2 is 2.
Array element 3 is 3.

相关问题