繁体   English   中英

如何从文本文件中读取整数和字符并将它们存储在单独的数组中?

[英]How do I read integers and characters from a text file and store them in separate arrays?

我正在尝试从包含诸如“Jane 30”、“Chris 40”等字符串的文件中逐行读取输入。 然后我需要将每个名称及其对应的数字存储在不同数组的相同索引中,因此“Jane”存储在一个索引为 0 的数组中,而 30 存储在一个索引为 0 的整数数组中。

这是我到目前为止的代码,但我正在努力弄清楚如何将整数提取到一个单独的数组中,并将字符提取到另一个数组中。 请帮忙。

#include stdio.h
#include stdlib.h
#include DarrensInfo.

int main()
{
FILE * coinfile;
coinfile = fopen("coins.txt", "r");
char names[150];
int change[50];
int x, y;

while(!feof(coinfile)){

    fgets(names, 150, coinfile);
    y = 0;

    for(x=0; names[x]; x++){

        if(names[x] <= '0' && names[x] <= '9'){

            change[y] = names[x];
            y++;

        }
    }

}

fclose(coinfile);

return 0;
}
#define COINS_MAX_LINES 150
#define MAX_LINE_LENGTH 100  
#define MAX_NAME_LENGTH 50
int main()
{
    FILE * coinfile;
    coinfile = fopen("coins.txt", "r");
    char line[MAX_LINE_LENGTH];
    char names[COINS_MAX_LINES][MAX_NAME_LENGTH];
    int change[COINS_MAX_LINES];
    int lineno = 0;
    int i = 0;
    while(fgets(line, MAX_LINE_LENGTH, coinfile))
    {
        sscanf(line, "%s %d", names[lineno], &change[lineno]);
        ++lineno;
    }

    fclose(coinfile);

    for (i = 0; i<lineno;++i)
        printf("Name = %s Change = %d\n", names[i], change[i]);

    return 0;

}

while 循环结束后,名称数组和更改数组将包含您想要的内容。 我已经在第二个循环中打印出来了

  1. 您需要一个字符数组数组。 将变量names定义为names[150][30] ,假设每个名称的长度不超过 30 个字符。
  2. 根据需要使用fgetsfscanf的组合将文件中的条目行解析为单独的变量
#include <stdio.h>
#include <stdlib.h>

int main()
{
  FILE * coinfile;
  coinfile = fopen("coins.txt", "r");
  char names[150][30];
  int change[150];
  int x = 0, y, i;

  char buf[100];
  while(!feof(coinfile)){
    if(fgets(buf, 100, coinfile) != NULL) { 
      sscanf(buf, "%s %d", names[x], &change[x]);
      x++;
    }
  }
  fclose(coinfile);

  puts("-------");
  for (int i = 0; i < x; i++)
    printf("%s %d\n", names[i], change[i]);

  return 0;
}

如果您试图解析可能看起来像“查理王 3”的名字,那么使用 scanf 会很困难。 在不使用静态大小的缓冲区的情况下做这种事情实际上并不难,这是一个习惯的好习惯。 你会想要避免fgets ,因为如果没有固定大小就很难使用。 请注意,增长数组是出了名的困难,因此我不对以下内容的正确性做出任何声明。 必须每隔几个月做一次这样的练习,以提醒我们为什么不在 C 中做这种事情:

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

FILE * Fopen(const char *, const char *);
void * Realloc(void *, size_t);

/* Remove trailing whitespace */
void trim_white(char *b, char *end)
{
        while( end > b && isspace(*--end)) {
                *end = '\0';
        }
}

int
main(int argc, char **argv)
{
        char *path = argc > 1 ? argv[1] : "stdin";
        FILE *coinfile = argc > 1 ? Fopen(path, "r") : stdin;
        size_t asize = 16;
        size_t bsize = 0;
        char *buf = NULL;
        char **names = Realloc(NULL, asize * sizeof *names);
        long *change = Realloc(NULL, asize * sizeof *change);
        unsigned line_number = 0;
        ssize_t char_read;
        while( buf = NULL, (char_read = getline(&buf, &bsize, coinfile)) != -1) {
                char *space;
                char *end;
                trim_white(buf, buf + char_read);
                space = strrchr(buf, ' ');
                if(space == NULL) {
                        fprintf(stderr, "Invalid input on line %d (no space)\n", line_number + 1);
                        exit(EXIT_FAILURE);
                }
                change[line_number] = strtol(space + 1, &end, 10);
                if(*end != '\0') {
                        fprintf(stderr, "Invalid input on line %d at '%s'\n", line_number + 1, space + 1);
                        exit(EXIT_FAILURE);
                }
                *space = '\0';
                names[line_number] = buf;

                if(++line_number == asize) {
                        asize *= 2;
                        names = Realloc(names, asize * sizeof *names);
                        change = Realloc(change, asize * sizeof *change);
                }
        }

        return EXIT_SUCCESS;
}

FILE *
Fopen(const char *path, const char *mode) {
        FILE *fp = fopen(path, mode);
        if( fp == NULL ) { perror(path); exit(EXIT_FAILURE); }
        return fp;
}

void *
Realloc(void *buf, size_t s)
{
        buf = realloc( buf, s );
        if( buf == NULL) { perror("realloc"); exit(EXIT_FAILURE); }
        return buf;
}

我正在尝试从包含诸如“Jane 30”、“Chris 40”等字符串的文件中逐行读取输入

您正在阅读一个可能包含诸如“Jane 30”、“Chris 40”等字符串的文件; 但也可能包含数百万个打字错误和/或其他错误; 因此您需要检测错误并清楚地告知用户错误是什么,以便他们可以轻松理解问题,然后找到错误,然后修复它。

由于这个原因,没有一个 C 库函数是有用的。

而是将解析器构建为有限状态机。 例如(未经测试):

    // State

    int state = 0;
    int column = 0;
    int line = 1;
    char current_name[MAX_NAME_LENGTH];
    int name_length;
    int number;

    // Main loop

    for(;;) {
        int c = fgetc(file);
        column++;
        switch(state) {

        case 0:  /* At start of new line */
            if(c == FEOF) {
                return OK;
            } else if(isdigit(c)) {
                printf("ERROR: Number found at start of line (missing name), on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isalpha(c)) {
                name_length = 0;
                current_name[name_length++] = c;
                state = 1;
            } else if(c == '\n') {
                line++
            } else if(isspace(c)) {
            } else {
                printf("ERROR: Bad character at start of line, on line %d at column %d\n", line, column);
                return NOT_OK;
            }
            break;

        case 1:  /* In middle of name */
            if(c == FEOF) {
                printf("ERROR: File ends in the middle of a name, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isdigit(c)) {
                printf("ERROR: No whitespace between name and number, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isalpha(c)) {
                if(name_length >= MAX_NAME_LENGTH) {
                    printf("ERROR: Name too long (max length is %d), on line %d at column %d\n", MAX_NAME_LENGTH, line, column);
                    return NOT_OK;
                }
                current_name[name_length++] = c;
            } else if(c == '\n') {
                printf("ERROR: No number after name, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isspace(c)) {
                state = 2;
            } else {
                printf("ERROR: Bad character in middle of name, on line %d at column %d\n", line, column);
                return NOT_OK;
            }
            break;

        case 2:  /* Between name and number */
            if(c == FEOF) {
                printf("ERROR: File ends after name, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isdigit(c)) {
                number = c - '0';
                state = 3;
            } else if(c == '\n') {
                printf("ERROR: No number after name, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isspace(c)) {
            } else {
                printf("ERROR: Bad character after name, on line %d at column %d\n", line, column);
                return NOT_OK;
            }
            break;

        case 4:  /* In middle of number */
            if(c == FEOF) {
                printf("ERROR: File ends in middle of number, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(isdigit(c)) {
                if(number > INT_MAX / 10) {
                    printf("ERROR: Number is too large, on line %d at column %d\n", line, column);
                    return NOT_OK;
                }
                number *= 10;
                if(number > INT_MAX - (c - '0') ) {
                    printf("ERROR: Number is too large, on line %d at column %d\n", line, column);
                    return NOT_OK;
                }
                number += c - '0';
            } else if(c == '\n') {
                create_new_entry(current_name, name_length, number);
                line++
                state = 0;
            } else if(isspace(c)) {
                state = 5;
            } else {
                printf("ERROR: Bad character after number, on line %d at column %d\n", line, column);
                return NOT_OK;
            }
            break;

        case 5:  /* Trailing white space before end of line */
            if(c == FEOF) {
                printf("ERROR: File ends between number and end of line, on line %d at column %d\n", line, column);
                return NOT_OK;
            } else if(c == '\n') {
                line++
                create_new_entry(current_name, name_length, number);
                state = 0;
            } else if(isspace(c)) {
            } else {
                printf("ERROR: Unknown characters between number and end of line, on line %d at column %d\n", line, column);
                return NOT_OK;
            }

        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM