Как я могу привести / скопировать из массива char, чтобы я мог сохранить его в массиве char? - PullRequest
0 голосов
/ 29 сентября 2018

Я работаю над проектом, который включает чтение и / или запись из текстового файла.В настоящее время единственными данными, которые я пытаюсь извлечь из текстового файла, являются имена.Моя цель состоит в том, чтобы иметь возможность хранить конкретные имена в массиве указателей символов, так что Char[n] будет присвоено имя для любого заданного n в массиве.

Проблема, с которой я, похоже, сталкиваюсь, заключается в том, чтоЯ устанавливаю свой элемент указателя символов на другой массив символов, в котором я сохраняю значение чтения из текстового файла.

Например, если я читаю имя из текстового файла и задаю Name[] равнымзатем это имя затем устанавливает Char[0] = Name, тогда Char[0] всегда будет меняться, когда Name делает.

Я, например, пытался записать строку непосредственно в Char[0], но затем моя программа просто зависалапосле того, как я попытаюсь прочитать и сохранить значение.Поэтому я прибег к этому извилистому пути назначения отдельного массива символов для сканируемого имени и установки для него одного из своих элементов.

#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;
}

Я занимался этим несколько дней иЯ нашел несколько интересных путей, которые могли бы решить мою проблему, например, копирование строки с помощью функции strcpy() или, возможно, приведение User к чему-либо.Однако пока все безрезультатно.

Буду признателен за любой совет относительно того, что, по вашему мнению, является наилучшим решением, если решение здесь неочевидно.Я хотел бы избегать делать все персонажи за персонажем, но я полагаю, что я был бы готов в долгосрочной перспективе.

Я прошу прощения за, возможно, неясный вопрос, я впервые задаю его, и япросто пытаюсь дать как можно больше контекста:)

Мой код компилируется без предупреждений или ошибок на данный момент.

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Вам необходимо выделить память для отдельного char[] для каждого имени, которое вы читаете из файла.

Например:

#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;
}

В качестве альтернативы:

#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;
}
0 голосов
/ 29 сентября 2018

явная ошибка, которую я вижу здесь:

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

повторное использование одного и того же буфера для всех имен пользователей не будет летать.С другой стороны, вы не можете использовать strcpy, потому что память не выделена.Вы можете использовать strdup, который выделяет и копирует строку.

UserNames[i] = strdup(User);

или для пуристов (поскольку strdup не является строго стандартом):

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

Какпримечание безопасности, поскольку буфер имеет длину 125 байт, я предлагаю ограничить вход, который он может принять, до 124 + nul-terminating:

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

Конечно, вам нужно освободить строки, когда они больше не нужныили вы получите утечки памяти, если ваша программа не закрывается или является частью большего кода.

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