在C中读取结构数组时仅打印txt文件的最后一行
我正在从一个txt文件读入一个结构数组。示例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
-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);