Назначьте глобальную переменную структуры за пределами main и Inside main - PullRequest
0 голосов
/ 19 октября 2018

проблема в том, когда я разделил код на другую функцию, и это происходит

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

//------Options -- change only true / false to trigger the function
bool hard_trace = false;
bool trace = true;
/*-------------------*/

//---------Defines----------
#define MAXSIZE 100 // maximum size of the characters in txt file to be buffed
/*----------------------*/

//---------Structs-----------
struct Matrix
{
    char *A[10];
    int depth;
};
/*--------------------------*/
//-----Variable----------
//-- global
char *B[3];
//- struct
struct Matrix matrixs ; // create new global struct
//-
//--
/*-----------------------*/

int convertCharToNumber(char target[1])
{
    int numbered = target[0] - 48;
    return numbered;
}

int generateDataFromFile(){
    //-- temped
    int currentLine = 1;
    int currentRow = 0;
    //-----------------
    FILE *fp;
    char line[MAXSIZE];

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

    while (fgets(line, MAXSIZE, fp) != NULL)
    {
        if(hard_trace){ // if it was enabled
            printf("current line : %d and length : %d\n", currentLine, strlen(line));
        }
        if (line[strlen(line) - 1] == '\n') // cutout the \n to make the txt easy to use
        {
            line[strlen(line) - 1] = '\0';
        }
        //appileToStruct(line,currentRow);
        matrixs.A[currentRow] = line;
        //if(trace) printf("%s\n", line);
        currentLine++; currentRow++;
    }
    if(trace) printf("Total line receive from txt file : %d\n" , currentLine-1); //if it was enabled
    fclose(fp);

    // ----------- assign the var
    matrixs.depth = currentLine - 1;
    //----------------------------

    //return 1;
}

void main(){
    generateDataFromFile();
    printf("Total : %d TXT : [%s]", strlen(matrixs.A[0]), matrixs.A[0]);
}

и вывод здесь

Итогострока получения из TXT-файла: 3

Всего: 10 TXT: []

.

Но это нормально, когда я непосредственно помещаю код в основную часть, как это

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

//------Options -- change only true / false to trigger the function
bool hard_trace = false;
bool trace = true;
/*-------------------*/

//---------Defines----------
#define MAXSIZE 100 // maximum size of the characters in txt file to be buffed
/*----------------------*/

//---------Structs-----------
struct Matrix
{
    char *A[10];
    int depth;
};
/*--------------------------*/
//-----Variable----------
//-- global
char *B[3];
//- struct
struct Matrix matrixs; // create new global struct
//-
//--
/*-----------------------*/

int convertCharToNumber(char target[1])
{
    int numbered = target[0] - 48;
    return numbered;
}

int main()
{
    //-- temped
    int currentLine = 1;
    int currentRow = 0;
    //-----------------
    FILE *fp;
    char line[MAXSIZE];

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

    while (fgets(line, MAXSIZE, fp) != NULL)
    {
        if (hard_trace)
        { // if it was enabled
            printf("current line : %d and length : %d\n", currentLine, strlen(line));
        }
        if (line[strlen(line) - 1] == '\n') // cutout the \n to make the txt easy to use
        {
            line[strlen(line) - 1] = '\0';
        }
        //appileToStruct(line,currentRow);
        matrixs.A[currentRow] = line;
        //if(trace) printf("%s\n", line);
        currentLine++;
        currentRow++;
    }
    if (trace)
        printf("Total line recieve from txt file : %d\n", currentLine - 1); //if it was enabled
    fclose(fp);

    // ----------- assign the var
    matrixs.depth = currentLine - 1;
    //----------------------------

    printf("Total : %d TXT : [%s]", strlen(matrixs.A[0]), matrixs.A[0]);
}

ВЫХОД

Общее количество полученных строк из текстового файла: 3

Всего: 10 TXT: [0000111100]

Можете ли вы объяснить мне, почему первый код не работает, я имею в виду, почему% s в printf не показывает вывод для меня и как я могу заставить работать первый код

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Когда вы делаете это:

matrixs.A[currentRow] = line;

Вы присваиваете адрес локального массива line элементу matrixs.A.В случае второй программы она печатает допустимое значение, потому что line все еще находится в области видимости.Но в первой программе line находится вне области видимости, поэтому matrixs.A[0] указывает на недопустимую память.Разыменование этого указателя вызывает неопределенное поведение .

Также во второй программе вы можете заметить, что каждый элемент matrixs.A содержит последнее прочитанное вами значение.Это опять же, потому что вы сохраняете адрес line в каждом из них.

Вместо этого вы должны сделать копию прочитанной строки и сохранить указатель на новую строку.Таким образом, 1) вы не сохраняете адрес локальной переменной, и 2) вы не храните один и тот же адрес в каждом элементе matrixs.A.

matrixs.A[currentRow] = strdup(line);
0 голосов
/ 19 октября 2018

Вот почему: matrixs.A[currentRow] = line;.

line локально для функции в первом случае.Эта инструкция присваивает указатель, она не копирует строки ( вы должны использовать strncpy вместо этого и не забудьте выделить необходимое пространство памяти на malloc), поэтому, когда все находится в main(), line четко определено в этой области, поэтому matrixs.A[0] является указателем на существующий line, тогда как в первом случае строка является локальным массивом, который принадлежит generateDataFromFile ().

Когда вы пытаетесьчтобы вывести matrixs.A[0] из main() (в первом случае), вы вызываете неопределенное поведение , потому что вы выполняете нарушение стека и пытаетесь получить доступ к некоторому адресу в стеке, который может содержатьвсе, что вы хотите в этот момент выполнения потока.

Предлагаемое исправление:

// instead of matrixs.A[currentRow] = line
size_t lineSize = strlen(line)+1;
matrixs.A[currentRow] = malloc(lineSize);
strncpy(matrixs.A[currentRow], line, lineSize);

И не забудьте free() выделенную память в конце.

...