Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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++ 在一行中的最后一个单词之后立即退出While循环_C++_Strtok - Fatal编程技术网

C++ 在一行中的最后一个单词之后立即退出While循环

C++ 在一行中的最后一个单词之后立即退出While循环,c++,strtok,C++,Strtok,我正在使用fgets从文件中读取以下行: C 12345678910十一 每个单词(C除外)都是一个列标题。因此,我的文件中有11列 我的目标是将这一行划分为每个单词的标记。另外,我需要计算有11个列标题。(列标题可以多于或少于11个) 我的问题是这行末尾的空格。以下是我正在使用的代码: while(1){ fgets(buffer,1024,filename); if (buffer[1] == 'C'){ char* str = buffer+2; char* pch;

我正在使用fgets从文件中读取以下行:

<代码> C 12345678910十一

每个单词(C除外)都是一个列标题。因此,我的文件中有11列

我的目标是将这一行划分为每个单词的标记。另外,我需要计算有11个列标题。(列标题可以多于或少于11个)

我的问题是这行末尾的空格。以下是我正在使用的代码:

while(1){
fgets(buffer,1024,filename);
if (buffer[1] == 'C'){
    char* str = buffer+2;
    char* pch;
    pch = strtok(str," ");
    while(pch != NULL){
        pch = strtok (NULL, " ");
        if (pch == NULL)break; //without this, ncol contains +1 the 
                               //amount of columns.
            ncol++;
    }
    break;
}
}
这个代码给了我ncol=11。而且效果很好。(请注意,我正在阅读的一行末尾只有一个空格)

但是,如果我在行尾没有空格,那么它给出ncol=10,并且不读取最后一列


我的目标是得到ncol=11,而不管not末尾是否有空格。我只想读最后一个单词,检查是否还有其他单词,如果没有,则退出。

如果更改此循环:

while(pch != NULL){
    pch = strtok (NULL, " ");
    if (pch == NULL)break; //without this, ncol contains +1 the 
                           //amount of columns.
        ncol++;
}
致:


因此,如果字符串中还剩下一些内容,那么当
pch
为空时,就有另一个字符串,因此在if中增加
ncol
。[您可能会发现,如果输入文件不是“格式良好的”
if(strlen(keep))
需要更彻底,但我假设您的输入是“良好的”]

您可以检查是否设置了令牌:

if (pch == NULL || *pch == '\0') break;

另一个更灵活的解决方案需要c++11支持

#include <iostream>
#include <string>
#include <vector>

template <typename Result, typename StringType>
void split(StringType const& contents, Result &result, StringType const& delimiters = "\n")
{
    typedef typename Result::value_type value_type;

    static_assert(std::is_same<value_type, StringType>::value, "std::is_same<value_type, StringType>::value == false,\n"
                  "The value_type of Result should be the same as StringType");

    typename StringType::size_type pos, last_pos = 0;
    while(true)
    {
        pos = contents.find_first_of(delimiters, last_pos);
        if(pos == StringType::npos)
        {
            pos = contents.length();

            if(pos != last_pos)
                result.emplace_back(contents.data() + last_pos, pos - last_pos);

            break;
        }
        else
        {
            if(pos != last_pos)
                result.emplace_back(contents.data() + last_pos, pos - last_pos );
        }

        last_pos = pos + 1;
    }
}

int main()
{             
    std::string const input = "#C one two three four five six seven eight nine ten eleven";
    std::vector<std::string> results;
    split(input, results, std::string(" "));
    for(auto const &data : results){
        std::cout<<data<<std::endl;
    }    

    return 0;
}
#包括
#包括
#包括
模板
无效拆分(StringType常量和内容、结果和结果、StringType常量和分隔符=“\n”)
{
typedef typename结果::值\类型值\类型;
静态断言(std::is_same::value,“std::is_same::value==false,\n”
“结果的值_类型应与StringType相同”);
typename StringType::size\u-type-pos,last\u-pos=0;
while(true)
{
pos=内容。查找(分隔符,最后一个pos)中的第一个;
if(pos==StringType::npos)
{
pos=contents.length();
如果(位置!=最后位置)
result.emplace_back(contents.data()+last_pos,pos-last_pos);
打破
}
其他的
{
如果(位置!=最后位置)
result.emplace_back(contents.data()+last_pos,pos-last_pos);
}
最后一个位置=位置+1;
}
}
int main()
{             
STD::String const输入=“γC 12345678910十一”;
std::矢量结果;
拆分(输入、结果、标准::字符串(“”);
用于(自动常量和数据:结果){

std::cout由于函数包含它从文件中读取的换行符,因此在结尾处有空格和没有空格的计数不同

因此,当行尾有空格时,换行符被视为一个单独的标记

为了克服这一问题,您应该在提供给
strtok
函数的令牌中包含换行符“\r”和“\n”,并远程调用
if(pch==NULL)break;

因此,代码将是

while(1){
    fgets(buffer,1024,filename);
    if (buffer[1] == 'C'){
        char* str = buffer+2;
        char* pch;
        pch = strtok(str," \r\n");
        while(pch != NULL){
            pch = strtok (NULL, " \r\n");
            //amount of columns.
            ncol++;
        }
        break;
    }
}

NULL和\0之间有什么区别@Philip@detraveller:
NULL
是一个指针值,
'\0'
是一个字符。实际上,您的编译器将int
0
从两者中提取出来,因此这只是为了澄清。
*pch=='\0'
是检查字符串长度是否为0的最快方法。
while(1){
    fgets(buffer,1024,filename);
    if (buffer[1] == 'C'){
        char* str = buffer+2;
        char* pch;
        pch = strtok(str," \r\n");
        while(pch != NULL){
            pch = strtok (NULL, " \r\n");
            //amount of columns.
            ncol++;
        }
        break;
    }
}