简体   繁体   中英

How do I cast /copy from a char array so that I may store it in a char pointer array?

I'm working on a project that involves reading and /or writing from a text file. Currently the only data I'm attempting to extract from the text file are names. My goal is to be able to store specific names in a character pointer array such that Char[n] will have a name assigned to it for any given n in the array.

The problem I seem to be having is that I'm setting my character pointer element to another character array where I'm storing the read value from the text file.

For example, if I read a name from the text file and set Name[] equal to that name then later set Char[0] = Name then Char[0] will always change when Name does.

I've attempted to write the string directly to Char[0] , for example, but then my program crashes just after I attempt to read and store the value. Therefore, I've resorted to this convoluted route of assigning a separate character array to the name I scan and setting one of my elements to it.

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

int main()
{
    FILE * inf = fopen("UserNames.txt", "r");
    char User[125];
    int err, TopNameNumber = 10;
    char *UserNames[TopNameNumber];

    if (inf == NULL) 
    { 
        printf("ERROR: No name file detected."); 
        return 0; 
    }

    for(int i = 0; i < TopNameNumber i++)
    {
        //This reads from my .txt file
        err = fscanf(inf, " %s", User);

        if(err == EOF)
            break;

        //This shows me what user was read from the text file
        printf("User read %d: %s\n", i+1, User); 

        //Program assigns the pointer address of User to Names[i]
        //This is where I'm having trouble
        UserNames[i] = User;
    }

    for(int c = 0; c < 3; c++)
    {
        // This always just prints out the last name read from the .txt file 
           for every name
        printf("Name #%d: %s\n", c, UserNames[c]);
    }

    return 0;
}

I've been at this for a few days and I've found some interesting avenues which could possibly solve my problem, such as copying the string with strcpy() function, or perhaps casting User to something. All to no avail so far, however.

I would appreciate any advice as to what you think is the best solution to pursue if the solution isn't obvious here. I would like to avoid doing everything character by character, but I suppose I would be willing to in the long run.

I apologize for perhaps an unclear question, this is my first time asking one, and I'm just trying to give as much context as possible :)

My code compiles with no warnings or errors as of right now.

the blatant error I see is here:

    //Program assigns the pointer address of User to Names[i]
    //This is where I'm having trouble
    UserNames[i] = User;

reusing the same buffer for all usernames isn't going to fly. On the other hand, you cannot use strcpy because no memory is allocated. You can use strdup which allocates & copies the string.

UserNames[i] = strdup(User);

or for the purists (since strdup isn't strictly in the standard):

UserNames[i] = malloc(strlen(User)+1);
strcpy(UserNames[i],User);

As a security side-note, since the buffer is 125 bytes long, I suggest limiting the input it can accept to 124+nul-termination:

err = fscanf(inf, " %124s", User);

Of course, you need to deallocate the strings when no longer used, or you'll get memory leaks if your program doesn't quit or is part of a bigger code.

free(UserNames[i]); // in a loop in the end, when no longer needed

You need to allocate memory for a separate char[] for each name you read from the file.

For example:

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

int main() {
    FILE *inf = fopen("UserNames.txt", "r");
    if (inf == NULL) {
        printf("ERROR: No name file detected.");
        return 0;
    }

    int err, c = 0;

    const int TopNameNumber = 10;
    char UserNames[TopNameNumber][125];

    for(int i = 0; i < TopNameNumber; i++) {
        err = fscanf(inf, " %124s", UserNames[c]);
        if (err == EOF)
            break;

        printf("User read %d: %s\n", c+1, UserNames[c]);
        ++c;
    }

    fclose(inf);

    for(int i = 0; i < c; i++) {
        printf("Name #%d: %s\n", i, UserNames[i]);
    }

    return 0;
}

Alternatively:

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

int main() {
    FILE *inf = fopen("UserNames.txt", "r");
    if (inf == NULL) {
        printf("ERROR: No name file detected.");
        return 0;
    }

    char User[125];
    int err, c = 0;

    const int TopNameNumber = 10;
    char* UserNames[TopNameNumber];

    for(int i = 0; i < TopNameNumber; i++) {
        err = fscanf(inf, " %124s", User);
        if (err == EOF)
            break;

        printf("User read %d: %s\n", c+1, User);

        UserNames[c] = malloc(strlen(User) + 1);
        if (UserNames[c] == NULL) {
            printf("ERROR: Memory allocation failed.");
            break;
        }

        strcpy(UserNames[c], User);
        ++c;
    }

    fclose(inf);

    for(int i = 0; i < c; i++) {
        printf("Name #%d: %s\n", i, UserNames[i]);
    }

    for(int i = 0; i < c; i++) {
        free(UserNames[i]);
    }

    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