从文本文件中提取字符串和整数,并将它们放入数组C语言中

时间:2017-10-03 18:41:37

标签: c arrays

我在这里遇到问题,我无法弄明白所以任何帮助都会受到赞赏,我有一个文本文件,其中包含用逗号分隔的字符串和整数,我想提取整数并将它们放入数组中并提取字符串并将它们放入另一个数组中,这是文本文件样本:

  

1,2,DFDS,DV,H,DFDD,wfdsf,E,3,4,饴,RSS,一个,6,8,5

这是代码:

onClick() {
    //code to control if you want to redirect or not
    history.push('http://yoururl.com');
}

3 个答案:

答案 0 :(得分:1)

要只读取整数并跳过其他任何内容,您可以使用以下方法

#include <stdio.h>

int main()
{
    FILE * f = fopen("file.txt","r");
    int number;
    int res;
    while((res = fscanf(f, "%d,",&number)) != EOF){
        if(res == 1){
            printf("%d,", number);
        }
        else{
            fscanf(f,"%*[^,],");
        }
    }
    printf("\n");
    return 0;
}

此处当res为1时 - 您可以将读取的数字添加到数组中。 当res为0时 - 你需要跳过下一步, 当fscanf返回EOF时 - 它意味着文件结尾是丰富的

EDIT2

我真的没有看到是什么阻止你扩展我的样本来做你想做的事。这是稍微扩展的版本

#include <stdio.h>

int skip(FILE* f) {
    for(;;)
    {
        int res = fgetc(f);
        if(res == EOF)
            return 0;

        if(res == ',')
            return 1;
    }
}
int main()
{
    FILE * f = fopen("file.txt","r");
    int number;
    int res;
    while((res = fscanf(f, "%d,",&number)) != EOF) {
        if(res == 1) {
            printf("number - %d\n", number);
            //add number to array
        }
        else {
            char buffer[100];
            if(fscanf(f,"%99[^,]",buffer ) == 1)
            {
                printf("string - %s\n", buffer);
                //add buffer to string array
            }
            if(!skip(f))
                break;
        }
    }
    printf("\n");
    return 0;
}

答案 1 :(得分:0)

我建议逐行阅读,将每一行拆分为令牌,检查每个令牌是否为数字并将其添加到numArray,否则添加到{{1} }。 请参阅以下代码,该代码使用stringArray进行标记并使用strtok来读取/检查数字。希望它有所帮助。

sscanf

输出:

void readDataByDelimiter(const char* File, char* stringArray[], int intArray[], int maxcount)
{
    FILE *myFile;
    myFile = fopen(File, "r");

    int intCount = 0;
    int stringCount = 0;

    char line[1000];
    while (myFile && fgets(line,sizeof(line),myFile)) {
        char* token = strtok(line, ",");
        while (token) {
            int num;
            if (sscanf(token, "%d", &num) == 1) {  // successfully scanned an int?
                if (intCount < maxcount) {
                    intArray[intCount++] = num;
                }
            }
            else {  // otherwise use as string
                if (stringCount < maxcount) {
                    stringArray[stringCount++] = strdup(token);
                }
            }
            token = strtok(NULL, ",");
        }
    }
}

int main() {

    int intArray[16] = { 0 };
    char* stringArray[16] = { NULL };

    readDataByDelimiter(DATAFILE, stringArray, intArray, 16);

    printf("numbers: \n");
    for (int i=0; intArray[i]; i++) {
        printf("%d ", intArray[i]);
    }
    printf("\nstrings: \n");
    for (int i=0; stringArray[i]; i++) {
        printf("%s ", stringArray[i]);
        free(stringArray[i]);
    }

}

答案 2 :(得分:0)

由于您的示例输入不遵循integer-string-integer-string等的清晰模式,您可能希望首先将每个项目作为文本字符串读取,然后将任何整数字符串转换为其对应的{使用int或类似函数的{1}}值。

那你怎么做的?

首先,您需要留出一个缓冲区来读取输入文本。

strtol

其中char buf[SIZE+1]; 是最大预期字符串的长度。请记住,在C中,字符串是字符值的序列,后跟0值终止符。字符串存储在SIZE数组中(或char用于宽字符串),而不是单个wchar_t个对象。

其次,我们需要将所有输入读作文本,但我们不希望在该文本中包含char分隔符或换行符。因此,我们不会使用,,而是使用%s转换说明符,它允许我们指定哪些字符想要成为输入的一部分。我们还想确保我们不会读取比%[大小要容纳的更多字符,因此我们也会在转换说明符中使用显式宽度。 不幸的是buf要求宽度作为说明符的一部分进行硬编码(您不能使用scanf并将宽度添加为额外的参数,就像您可以使用*)。这对屁股来说是一个很大的痛苦,所以为了解决这个问题,我们必须要有一个宏观的创意:

printf

我们将像这样使用宏:

#define SIZE 20
#define FMT2(x) #x
#define FMT(x) "%" FMT2(x) "[^,\n]"

宏观扩张后,将成为

scanf( FMT(SIZE), buf );

表示“从标准输入中读取文本,直到我们看到逗号或换行符 OR 我们读取了20个字符,并将结果存储到scanf( "%20[^,\n]", buf ); // note no & operator on buf - not used for array expressions ”。

最后,我们需要检查每个输入以查看它是否是整数字符串(buf"1"等)。这样做的简单方法是使用"234"库函数,该函数将尝试将字符串转换为等效的整数。它将返回指向不属于合法整数字符串的第一个字符的指针 - 如果该字符不是空格或字符串终止符,则输入不是有效整数:

strtol

以下是一个将所有这些放在一起的独立程序:

char *chk;
int tmp = strtol( buf, &chk, 0 );
if ( !isspace( *chk ) && *chk != 0 )
{
  // tmp is not a valid integer string
}

运行您的样本输入,输出为:

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

#define SIZE 20
#define FMT2(x) #x
#define FMT(x) "%" FMT2(x)  "[^,\n]"

int main( void )
{
  int iValues[100];
  char sValues[100][SIZE+1];

  size_t iCount = 0;
  size_t sCount = 0;
  int    r = 1;

  char buf[SIZE+1] = {0};

  /**
   * Loop until one of the following is true:
   *
   *   - End of file or error on input
   *   - We see the string "end" (which will be included in the list of strings)
   *   - We've read 100 strings or integers
   */
  while ( strcmp( buf, "end" ) && r == 1 && iCount < 100 && sCount < 100 )
  {
    /**
     * The "%*c" tells scanf to read and discard the next character
     * from the input stream; if we don't do that, the trailing comma
     * or newline will foul up the next read and we'll get stuck in
     * an infinite loop.  
     */ 
    if ( ( r = scanf( FMT(SIZE) "%*c", buf )) == 1)
    {
      char *chk = 0;
      int tmp = (int) strtol( buf, &chk, 0 );
      if ( !isspace( *chk ) && *chk != 0 )
      {
        /**
         * The input string contains at least one non-numeric character,
         * so we add it to the sValues array.
         */
        strcpy( sValues[sCount++], buf );
      }
      else
      {
        /**
         * The input string is an integer, so we add it to the iValues
         * array
         */
        iValues[iCount++] = tmp;
      }
    }
  }

  for ( size_t i = 0; i < iCount; i++ )
    printf( "iValues[%zu] = %d\n", i, iValues[i] );

  for ( size_t i = 0; i < sCount; i++ )
    printf( "stringValues[%zu] = %s\n", i, sValues[i] );

  return 0;
}

此代码未处理的一个问题 - 如果输入的字符串长度大于缓冲区的大小以容纳,则会将其拆分为两个(或更多)字符串(由于{{而丢弃一个字符) 1}}说明符):

$ ./delim
1,2,dfds,dv,h,dfdd,wfdsf,e,3,4,yee,rss,a,6,8,5
iValues[0] = 1
iValues[1] = 2
iValues[2] = 3
iValues[3] = 4
iValues[4] = 6
iValues[5] = 8
iValues[6] = 5
stringValues[0] = dfds
stringValues[1] = dv
stringValues[2] = h
stringValues[3] = dfdd
stringValues[4] = wfdsf
stringValues[5] = e
stringValues[6] = yee
stringValues[7] = rss
stringValues[8] = a

你会想要决定如何处理,但现在这应该让你去。