我正在编写的代码遇到麻烦。程序通过将文件作为字符串读取到char结构变量中来从文件中读取,并将其传递给trimField函数以修剪程序。这是我们得到的输入文本文件:
BROWN DANIELLA 810805748 562431322143323235411221 4213414131344422312122
DEREK SAMATHA I 002 10011313243433233344312212321342123 14212224242131121
SIMPSON BRETT 3844342323232233 33412342212342113221331132411112132
TOMATO A LUKE 811327785 15328003 4214341213331232354112432321532412124211142232213242
我在文件中读取的此函数看起来像这样,其中数字来自结构变量(即char Name [21];):
void readData(std::ifstream inFileStream, Scantron &inputRecord) {
std::string incomingData;
getline(inFileStream, incomingData);
if(!inputTestFile.eof) {
for(int i = 0; i < incomingData; i++) {
std::cin.get(inputRecord[i].Name, 21, ' ');
std::cin.get(inputRecord[i].Id, 11, ' ');
std::cin.get(inputRecord[i].CRN, 6, ' ');
std::cin.get(inputRecord[i].testCode, 3, ' ');
std::cin.get(inputRecord[i].specialCode, 4, ' ');
std::cin.get(inputRecord[i].score, 4, ' ');
std::cin.get(inputRecord[i].answerArray, 61, ' ');
}
}
}
我当前调用trimField函数的函数如下:
csvRecord transformDataToCSV(Scantron inputRecord){
csvRecord outputRecord;
trimField(inputRecord.Name, outputRecord.Name);
trimField(inputRecord.Id, outputRecord.Id);
trimField(inputRecord.score, outputRecord.score);
for(int i = 0; i < 60; ++i) {
outputRecord.answerArray[i] = inputRecord.answerArray[i];
trimField(inputRecord.answerArray, outputRecord.score);
}
return outputRecord;
}
并且trimField的标题必须如下所示:
// remove trailing spaces from fieldIn cstring and place in fieldOut cstring. If entire field is blank place one space followed by \0.
void trimField(char fieldIn[], char &fieldOut[] ) {
}
我不确定在修剪文件时该如何开始,并且有太多不同的在线处理方法,这使我很难理解如何执行此操作。
答案 0 :(得分:0)
我很困惑为什么您仍然使用cstring。更令人困惑的是,您尝试为输出传递一个引用数组。这不会编译:
error: declaration of ‘fieldOut’ as array of references
void trimField2(char fieldIn[], char &fieldOut[]) {
^
尽管如此,这是一个简单的解决方案:先计算空格数,最后计算空格数,然后仅复制剩下的内容:
void trimField(char fieldIn[], char fieldOut[] ) {
int i=0;
// skip left spaces with i
while (fieldIn[i] && isspace(fieldIn[i]) )
i++;
// skip right spaces starting from end with j (relative to i)
int j=strlen(fieldIn+i);
while (j && isspace (fieldIn[j+i-1]) )
j--;
strncpy(fieldOut, fieldIn+i, j);
fieldOut[j]='\0';
}
请注意,此函数是不安全的,因为它没有将输出的最大长度作为参数考虑在内,因此存在缓冲区溢出的风险。另外,由于输入未定义为const
,因此容易出错。
我建议您使用一个变体,该变体返回一个真实的C ++字符串并以一个const缓冲区作为输入:
std::string trimField(const char fieldIn[]) {
const char *p, *q,*r;
for (p=fieldIn; *p && isspace(*p); p++ ) // skip left spaces
;
for (q=r=p; *q; q++) // sorry for the tripple assignment ;-)
if (!isspace (*q))
r=q; // keep trace of last non white
return std::string (p, r+1);
}
为方便起见,我切换到指针。为避免在第一个非空格字符之后读取两次字符,我们同时搜索输入字符串(q)的末尾并跟踪非白色字符(r)。最后,我们基于起点和终点的指针/迭代器构造一个字符串。