Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中读取结构数组时仅打印txt文件的最后一行_C_Arrays_File_Loops_Struct - Fatal编程技术网

在C中读取结构数组时仅打印txt文件的最后一行

在C中读取结构数组时仅打印txt文件的最后一行,c,arrays,file,loops,struct,C,Arrays,File,Loops,Struct,我正在从一个txt文件读入一个结构数组。示例txt: -4.5 -1 0 0 4.0 1 0 0 8 0 1 2 12.1 0 -6 1 -3.2 2.5 -3.0 4 每行的4个值对应于结构中的4个值。该文件最多可包含100行(最大值定义为100)。使用以下代码,我尝试将每一行存储到struct数组的相应索引中,然后打印: FILE *fileName = NULL; typedef struct chargeData_struct { double Q, x, y, z; } Ch

我正在从一个txt文件读入一个结构数组。示例txt:

-4.5 -1 0 0
4.0 1 0 0
8 0 1 2
12.1 0 -6 1
-3.2 2.5 -3.0 4
每行的4个值对应于结构中的4个值。该文件最多可包含100行(最大值定义为100)。使用以下代码,我尝试将每一行存储到struct数组的相应索引中,然后打印:

FILE *fileName = NULL;
typedef struct chargeData_struct {
    double Q, x, y, z;
} ChargeData;
ChargeData values[MAX], *p = values;

fileName = fopen("charge2.txt", "r");
if (fileName == NULL)
{
    printf("ERROR: Could not open file.");
}

int k = 0;
while (fscanf(fileName, "%lf %lf %lf %lf", &p[k].Q, &p[k].x, &p[k].y, &p[k].z) != EOF);
{
    printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
    k++;
}
fclose(fileName);

但是,仅打印txt文件的最后一行。每次都会覆盖结构数组的同一索引吗?

您使用了一个额外的分号,这会造成所有问题,如下所示:

while (fscanf(...) != EOF);
{
   ...
去掉它,你就会没事了

您的代码发生的情况是,
while(…)与此等效:

while(...)
{
    ; // do nothing
}
因此不会进入循环的身体(你认为是身体的那一个)(因为实际的身体什么都不做)。但是
scanf()
继续解析文件,然后执行代码的这一部分:

{
    printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
    k++;
}

独立地,将大括号视为它们想要说明的范围。

您使用了一个额外的分号,这会造成所有的麻烦,这里:

while (fscanf(...) != EOF);
{
   ...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define LINE_BUFFER_LEN   (512)
#define RESERVE_NEWLINDE          0
#define AUTO_FILTER_NEWLINDE      1

typedef int (* LINE_READER)(char * pstrLine, int uiBufferLen, void * pvData);

typedef struct st_HW_SSP_CONFIG
{
    const char * pstrConfigPath;
    LINE_READER pfLineReader;
    FILE * pstFile;
    void * pvData;
    int CurrentLine;
    int Flag;
} CONFIG_ST;

int CloseConfig(CONFIG_ST * pstConfig)
{
    if (!pstConfig)
    {
        // record error
        return -1;
    }
    if (fclose(pstConfig->pstFile))
    {
        // record error
    }
    return 0;
}

int OpenConfigFile(const char * pstrFilePath, CONFIG_ST * pstConfig)
{
    FILE * pstFile = NULL;
    if ((!pstrFilePath) || (!pstConfig))
    {
        return -1;
    }
    pstFile = fopen(pstrFilePath, "r");
    if (!pstFile)
    {
        return -1;
    }
    pstConfig->pstFile = pstFile;
    pstConfig->pstrConfigPath = pstrFilePath;
    pstConfig->Flag = RESERVE_NEWLINDE;
    return 0;
}

int IsNullStr(const char *pcStr)
{
    const char *pcTmp = pcStr;
    while ('\0' != *pcTmp)
    {
        if (!isspace(*pcTmp))
        {
            return 0;
        }

        pcTmp++;
    }
    return 1;
}

int IsEffectiveLine(char acFileLineBuffer[LINE_BUFFER_LEN])
{
    if (0 == strlen(&acFileLineBuffer[0]))
    {
        return 0;
    }
    if ('#' == acFileLineBuffer[0]) // strip as a comment line
    {
        return 0;
    }
    if (IsNullStr(&acFileLineBuffer[0]))
    {
        return 0;
    }
    return 1;
}

void FilterNewLine(char* pcLine,  int MaxNumLen)
{
    int uiLen = strlen(pcLine);
    if (uiLen > 1)
    {
        if ('\n' == pcLine[uiLen - 1])
        {
            pcLine[uiLen - 1] = '\0';

            if (uiLen > 2)
            {
                if ('\r' == pcLine[uiLen - 2])
                {
                    pcLine[uiLen - 2] = '\0';
                }
            }
        }
    }
    return;
}

int ReadConfigFile(CONFIG_ST * pstConfig)
{
    char acFileLineBuffer[LINE_BUFFER_LEN] = {0};
    char * pstrRead = NULL;
    int Ret = 0;

    if (!pstConfig)
    {
        return -1;
    }
    if ((!pstConfig->pstFile) || (!pstConfig->pfLineReader))
    {
        return -1;
    }

    rewind(pstConfig->pstFile);
    pstConfig->CurrentLine = 0;

    do
    {
        memset((void *)&acFileLineBuffer[0], 0, LINE_BUFFER_LEN);
        pstrRead = fgets(&acFileLineBuffer[0], LINE_BUFFER_LEN - 1, pstConfig->pstFile);
        if (pstrRead)
        {
            pstConfig->CurrentLine ++;

            if (0 == IsEffectiveLine(acFileLineBuffer))
            {
                continue;
            }

            if (AUTO_FILTER_NEWLINDE == pstConfig->Flag)
            {
                FilterNewLine(acFileLineBuffer, LINE_BUFFER_LEN - 1);
            }

            if (pstConfig->pfLineReader)
            {
                Ret = pstConfig->pfLineReader(&acFileLineBuffer[0],
                                              LINE_BUFFER_LEN,
                                              pstConfig->pvData);

                if (Ret)
                {
                    break;
                }
            }
        }
    }
    while (pstrRead);
    return Ret;
}

int ReadConfigFileEx(const char * pFilePath,
                     LINE_READER pfReader,
                     void * pData, int Flag)
{
    int Ret = 0;
    CONFIG_ST stConfig = {0};

    Ret = OpenConfigFile(pFilePath, &stConfig);
    if (Ret)
    {
        return Ret;
    }

    stConfig.pfLineReader = pfReader;
    stConfig.pvData = pData;
    stConfig.Flag = Flag;
    Ret = ReadConfigFile(&stConfig);
    CloseConfig(&stConfig);
    return Ret;
}


int StringSplit(char *pcStr, char cFlag,
                char * pstArray[], int MaxNum,
                int *pNum)
{
    char * pcStrTemp = 0;
    unsigned int uiIndex = 0;

    pcStrTemp = pcStr;

    while (pcStrTemp)
    {
        pstArray[uiIndex] = pcStrTemp;
        pcStrTemp = strchr(pcStrTemp, cFlag);
        if (pcStrTemp)
        {
            *pcStrTemp = '\0';
            pcStrTemp ++;
            uiIndex ++;
        }
        if (uiIndex >= MaxNum)
        {
            break;
        }
    }

    if (0 != MaxNum)
    {
        *pNum = uiIndex >= MaxNum ? (MaxNum - 1) : uiIndex;
    }
    else
    {
        *pNum = 0;
    }

    return 0;
}

int MyLineReader(char * pstrLine, int uiBufferLen, void * pvData)
{
    printf("Read line:[%s]\r\n", pstrLine);

    char *pArray[8] = {0};
    int Num = 0;
    int index = 0;
    StringSplit(pstrLine, ' ', pArray, 8, &Num);
    for (index = 0; index <= Num; index ++)
    {
        printf("Get value :[%s]\r\n", pArray[index]);
    }

    return 0;
}

int main(int argc, char * argv[])
{
    int ret = 0;

    if (argc != 2)
    {
        printf("Please input file to read.\r\n");
        return 0;
    }

    ret = ReadConfigFileEx(argv[1], MyLineReader, NULL, AUTO_FILTER_NEWLINDE);
    if (ret)
    {
        printf("Open file error.\r\n");
    }

    return 0;
}
去掉它,你就会没事了

您的代码发生的情况是,
while(…)与此等效:

while(...)
{
    ; // do nothing
}
因此不会进入循环的身体(你认为是身体的那一个)(因为实际的身体什么都不做)。但是
scanf()
继续解析文件,然后执行代码的这一部分:

{
    printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
    k++;
}
独立地,将花括号视为它们想要说明的范围。

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

#define LINE_BUFFER_LEN   (512)
#define RESERVE_NEWLINDE          0
#define AUTO_FILTER_NEWLINDE      1

typedef int (* LINE_READER)(char * pstrLine, int uiBufferLen, void * pvData);

typedef struct st_HW_SSP_CONFIG
{
    const char * pstrConfigPath;
    LINE_READER pfLineReader;
    FILE * pstFile;
    void * pvData;
    int CurrentLine;
    int Flag;
} CONFIG_ST;

int CloseConfig(CONFIG_ST * pstConfig)
{
    if (!pstConfig)
    {
        // record error
        return -1;
    }
    if (fclose(pstConfig->pstFile))
    {
        // record error
    }
    return 0;
}

int OpenConfigFile(const char * pstrFilePath, CONFIG_ST * pstConfig)
{
    FILE * pstFile = NULL;
    if ((!pstrFilePath) || (!pstConfig))
    {
        return -1;
    }
    pstFile = fopen(pstrFilePath, "r");
    if (!pstFile)
    {
        return -1;
    }
    pstConfig->pstFile = pstFile;
    pstConfig->pstrConfigPath = pstrFilePath;
    pstConfig->Flag = RESERVE_NEWLINDE;
    return 0;
}

int IsNullStr(const char *pcStr)
{
    const char *pcTmp = pcStr;
    while ('\0' != *pcTmp)
    {
        if (!isspace(*pcTmp))
        {
            return 0;
        }

        pcTmp++;
    }
    return 1;
}

int IsEffectiveLine(char acFileLineBuffer[LINE_BUFFER_LEN])
{
    if (0 == strlen(&acFileLineBuffer[0]))
    {
        return 0;
    }
    if ('#' == acFileLineBuffer[0]) // strip as a comment line
    {
        return 0;
    }
    if (IsNullStr(&acFileLineBuffer[0]))
    {
        return 0;
    }
    return 1;
}

void FilterNewLine(char* pcLine,  int MaxNumLen)
{
    int uiLen = strlen(pcLine);
    if (uiLen > 1)
    {
        if ('\n' == pcLine[uiLen - 1])
        {
            pcLine[uiLen - 1] = '\0';

            if (uiLen > 2)
            {
                if ('\r' == pcLine[uiLen - 2])
                {
                    pcLine[uiLen - 2] = '\0';
                }
            }
        }
    }
    return;
}

int ReadConfigFile(CONFIG_ST * pstConfig)
{
    char acFileLineBuffer[LINE_BUFFER_LEN] = {0};
    char * pstrRead = NULL;
    int Ret = 0;

    if (!pstConfig)
    {
        return -1;
    }
    if ((!pstConfig->pstFile) || (!pstConfig->pfLineReader))
    {
        return -1;
    }

    rewind(pstConfig->pstFile);
    pstConfig->CurrentLine = 0;

    do
    {
        memset((void *)&acFileLineBuffer[0], 0, LINE_BUFFER_LEN);
        pstrRead = fgets(&acFileLineBuffer[0], LINE_BUFFER_LEN - 1, pstConfig->pstFile);
        if (pstrRead)
        {
            pstConfig->CurrentLine ++;

            if (0 == IsEffectiveLine(acFileLineBuffer))
            {
                continue;
            }

            if (AUTO_FILTER_NEWLINDE == pstConfig->Flag)
            {
                FilterNewLine(acFileLineBuffer, LINE_BUFFER_LEN - 1);
            }

            if (pstConfig->pfLineReader)
            {
                Ret = pstConfig->pfLineReader(&acFileLineBuffer[0],
                                              LINE_BUFFER_LEN,
                                              pstConfig->pvData);

                if (Ret)
                {
                    break;
                }
            }
        }
    }
    while (pstrRead);
    return Ret;
}

int ReadConfigFileEx(const char * pFilePath,
                     LINE_READER pfReader,
                     void * pData, int Flag)
{
    int Ret = 0;
    CONFIG_ST stConfig = {0};

    Ret = OpenConfigFile(pFilePath, &stConfig);
    if (Ret)
    {
        return Ret;
    }

    stConfig.pfLineReader = pfReader;
    stConfig.pvData = pData;
    stConfig.Flag = Flag;
    Ret = ReadConfigFile(&stConfig);
    CloseConfig(&stConfig);
    return Ret;
}


int StringSplit(char *pcStr, char cFlag,
                char * pstArray[], int MaxNum,
                int *pNum)
{
    char * pcStrTemp = 0;
    unsigned int uiIndex = 0;

    pcStrTemp = pcStr;

    while (pcStrTemp)
    {
        pstArray[uiIndex] = pcStrTemp;
        pcStrTemp = strchr(pcStrTemp, cFlag);
        if (pcStrTemp)
        {
            *pcStrTemp = '\0';
            pcStrTemp ++;
            uiIndex ++;
        }
        if (uiIndex >= MaxNum)
        {
            break;
        }
    }

    if (0 != MaxNum)
    {
        *pNum = uiIndex >= MaxNum ? (MaxNum - 1) : uiIndex;
    }
    else
    {
        *pNum = 0;
    }

    return 0;
}

int MyLineReader(char * pstrLine, int uiBufferLen, void * pvData)
{
    printf("Read line:[%s]\r\n", pstrLine);

    char *pArray[8] = {0};
    int Num = 0;
    int index = 0;
    StringSplit(pstrLine, ' ', pArray, 8, &Num);
    for (index = 0; index <= Num; index ++)
    {
        printf("Get value :[%s]\r\n", pArray[index]);
    }

    return 0;
}

int main(int argc, char * argv[])
{
    int ret = 0;

    if (argc != 2)
    {
        printf("Please input file to read.\r\n");
        return 0;
    }

    ret = ReadConfigFileEx(argv[1], MyLineReader, NULL, AUTO_FILTER_NEWLINDE);
    if (ret)
    {
        printf("Open file error.\r\n");
    }

    return 0;
}
#包括 #包括 #包括 #定义行缓冲区长度(512) #定义保留\u NEWLINDE 0 #定义自动过滤器\u NEWLINDE 1 typedef int(*行读取器)(字符*pstrLine,int-uiBufferLen,void*pvData); 类型定义结构st_硬件SSP_配置 { const char*pstrconfig路径; 行读取器pfLineReader; 文件*pstFile; void*pvData; int电流线; int标志; }配置; int CloseConfig(CONFIG_ST*pstConfig) { 如果(!pstConfig) { //记录错误 返回-1; } 如果(fclose(pstConfig->pstFile)) { //记录错误 } 返回0; } int OpenConfigFile(const char*pstrFilePath,CONFIG\u ST*pstConfig) { FILE*pstFile=NULL; 如果((!pstrFilePath)| |(!pstConfig)) { 返回-1; } pstFile=fopen(pstrFilePath,“r”); 如果(!pstFile) { 返回-1; } pstConfig->pstFile=pstFile; pstConfig->pstrConfigPath=pstrFilePath; pstConfig->Flag=RESERVE\u NEWLINDE; 返回0; } int IsNullStr(常量字符*pcStr) { 常量字符*pcTmp=pcStr; 而('\0'!=*pcTmp) { 如果(!isspace(*pcTmp)) { 返回0; } pcTmp++; } 返回1; } int IsEffectiveLine(char acFileLineBuffer[LINE\u BUFFER\u LEN]) { if(0==strlen(&acFileLineBuffer[0])) { 返回0; } if('#'==acFileLineBuffer[0])//将条带作为注释行 { 返回0; } if(IsNullStr(&acFileLineBuffer[0])) { 返回0; } 返回1; } void FilterNewLine(char*pcLine,int-maxmlen) { int uiLen=strlen(pcLine); 如果(uiLen>1) { 如果('\n'==pcLine[uiLen-1]) { pcLine[uiLen-1]='\0'; 如果(uiLen>2) { 如果('\r'==pcLine[uiLen-2]) { pcLine[uiLen-2]='\0'; } } } } 返回; } int ReadConfigFile(CONFIG_ST*pstConfig) { char acFileLineBuffer[LINE_BUFFER_LEN]={0}; char*pstrRead=NULL; int-Ret=0; 如果(!pstConfig) { 返回-1; } 如果((!pstConfig->pstFile)|(!pstConfig->pfLineReader)) { 返回-1; } 倒带(pstConfig->pstFile); pstConfig->CurrentLine=0; 做 { memset((void*)和acFileLineBuffer[0],0,LINE\u BUFFER\u LEN); pstrRead=fgets(&acFileLineBuffer[0],行缓冲区长度-1,pstConfig->pstFile); 如果(pstrRead) { pstConfig->CurrentLine++; 如果(0==IsEffectiveLine(acFileLineBuffer)) { 继续; } if(自动过滤器\u NEWLINDE==pstConfig->Flag) { FilterNewLine(acFileLineBuffer,LINE_BUFFER_LEN-1); } 如果(pstConfig->pfLineReader) { Ret=pstConfig->pfLineReader(&acFileLineBuffer[0], 行缓冲区, pstConfig->pvData); 如果(Ret) { 打破 } } } } while(pstrRead); 返回Ret; } int ReadConfigFileEx(常量字符*pFilePath, 行_读取器pfReader, void*pData,int标志) { int-Ret=0; CONFIG_ST stConfig={0}; Ret=OpenConfigFile(pFilePath和stConfig); 如果(Ret) { 返回Ret; } stConfig.pfLineReader=pfReader; stConfig.pvData=pData; stConfig.Flag=Flag; Ret=ReadConfigFile(&stConfig); CloseConfig(&stConfig); 返回Ret; } int StringSplit(char*pcStr,char cFlag, char*pstArray[],int MaxNum, int*pNum) { char*pcStrTemp=0; 无符号整数指数=0; pcStrTemp=pcStr; while(pcStrTemp) { pstArray[uiIndex]=pcStrTemp; pcStrTemp=strchr(pcStrTemp,cFlag); 如果(pcStrTemp) { *pcStrTemp='\0'; pcStrTemp++; uiIndex++; } 如果(uiIndex>=MaxNum) { 打破 } } 如果(0!=MaxNum) { *pNum=uiIndex>=MaxNum?(MaxNum-1):uiIndex; } 其他的 { *pNum=0; } 返回0; } 内部MyLineReader(char*pstrLine,内部uiBufferLen,void*pvData) { printf(“读取行:[%s]\r\n”,pstrLine);