简体   繁体   中英

C - reading ints and chars into arrays from a file

I have a .txt file with values written in this format: LetterNumber, LetterNumber, LetterNumber etc (example: A1, C8, R43, A298, B4). I want to read the letters and the numbers into two separate arrays (example: array1 would be ACRAB; array2 would be 1 8 43 298 4). How can I make it happen?

At the moment I only figured out how to read all the values, both numbers and letters and the commas and everything, into one array of chars:

FILE *myfile;
myfile = fopen("input1.txt", "r");
char input[677]; //I know there are 676 characters in my .txt file
int i;
if (myfile == NULL) {
    printf("Error Reading File\n");
    exit (0);
}    
for (i=0; i<677; i++) {
    fscanf(myfile, "%c", &input[i]);
}
fclose(myfile);

But ideally I want two arrays: one containing only letters and one containing only numbers. Is it even possible?

I would appreciate any kind of help, even just a hint. Thank you!

Define another array for integers,

int inputD[677]; 

Then in for loop read one char, one integer and one space char at a time.

fscanf(myfile, " %c%d %*[,] ", &input[i], &inputD[i]);

I would actually define a struct to keep letter and number together; the data format strongly suggests that they have a close relation. Here is a program that exemplifies the idea.

The scanf format is somewhat tricky to get right (meaning as simple as possible, but no simpler). RoadRunner, for example, forgot to skip whitespace preceding the letter in his answer.

It helps that we have (I assume) only single letters. It is helpful to remember that all standard formats except %c skip whitespace. (Both parts of that sentence should be remembered.)

#include<stdio.h>

#define ARRLEN 10000

// Keep pairs of data together in one struct.
struct CharIntPair
{
    char letter;
    int number;
};

// test data. various space configurations
// char *data = " A1, B22 , C333,D4,E5   ,F6,  Z12345";

void printParsedPairs(struct CharIntPair pairs[], int count)
{
    printf("%d pairs:\n", count);
    for(int i = 0; i<count; i++)
    {
        printf("Pair %6d. Letter: %-2c, number: %11d\n", i, pairs[i].letter, pairs[i].number);
    }
}

int main()
{
    setbuf(stdout, NULL);
    setbuf(stdin, NULL);

    // For the parsing results
    struct CharIntPair pairs[ARRLEN];
    //char dummy [80];
    int parsedPairCount = 0;
    for(parsedPairCount=0; parsedPairCount<ARRLEN; parsedPairCount++)
    {
        // The format explained>
        // -- " ": skips any optional whitespace
        // -- "%c": reads the next single character
        // -- "%d": expects and reads a number after optional whitespace
        //    (the %d format, like all standard formats except %c,
        //    skips whitespace).
        // -- " ": reads and discards optional whitespace 
        // -- ",": expects, reads and discards a comma.
        // The position after this scanf returns with 2 will be 
        // before optional whitespace and the next letter-number pair.
        int numRead 
            = scanf(" %c%d ,", 
                    &pairs[parsedPairCount].letter, 
                    &pairs[parsedPairCount].number);

        //printf("scanf returned %d\n", numRead);
        //printf("dummy was ->%s<-\n", dummy);
        if(numRead < 0)  // IO error or, more likely, EOF. Inspect errno to tell.
        {
            printf("scanf returned %d\n", numRead);
            break; 
        }
        else if(numRead == 0)
        {           
            printf("scanf returned %d\n", numRead);
            printf("Data format problem: No character? How weird is that...\n");
            break;
        }
        else if(numRead == 1)
        {
            printf("scanf returned %d\n", numRead);
            printf("Data format problem: No number after first non-whitespace character ->%c<- (ASCII %d).\n",
                    pairs[parsedPairCount].letter, (int)pairs[parsedPairCount].letter);
            break;
        }
        // It's 2; we have parsed a pair.
        else
        {
            printf("Parsed pair %6d. Letter: %-2c, number: %11d\n", parsedPairCount,
            pairs[parsedPairCount].letter, pairs[parsedPairCount].number);
        }
    }
    printf("parsed pair count: %d\n", parsedPairCount);
    printParsedPairs(pairs, parsedPairCount);

}

I was struggling a bit with my cygwin environment with bash and mintty on a Windows 8. The %c would sometimes encounter a newline (ASCII 10) which should be eaten by the preceding whitespace-eating space, derailing the parsing. (More robust parsing would, after an error, try to read char by char until the next comma is encountered, and try to recover from there.)

This happened when I typed Ctr-D (or, I think, also Ctr-Z in a console window) in an attempt to signal EOF; the following enter key stroke would cause a newline to "reach" the %c. Of course text I/O in a POSIX emulation on a Windows system is tricky; I must assume that somewhere between translating CR-NL sequences back and forth this bug slips in. On a linux system via ssh/putty it works as expected.

You basically just have to create one char array and one int array, then use fscanf to read the values from the file stream.

For simplicity, using a while loop in this case makes the job easier, as you can read the 2 values returned from fscanf until EOF .

Something like this is the right idea:

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

// Wasn't really sure what the buffer size should be, it's up to you. 
#define MAXSIZE 677

int 
main(void) {
    FILE *myFile;
    char letters[MAXSIZE];
    int numbers[MAXSIZE], count = 0, i;

    myFile = fopen("input1.txt", "r");
    if (myFile == NULL) {
        fprintf(stderr, "%s\n", "Error reading file\n");
        exit(EXIT_FAILURE);
    }

    while (fscanf(myFile, " %c%d ,", &letters[count], &numbers[count]) == 2) {
        count++;
    }

    for (i = 0; i < count; i++) {
        printf("%c%d ", letters[i], numbers[i]);
    }
    printf("\n");

    fclose(myFile);

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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