Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ strtok读取长度_C++_Strtok - Fatal编程技术网

C++ strtok读取长度

C++ strtok读取长度,c++,strtok,C++,Strtok,以下是文本文件的内容: SQUARE 2 SQUARE RECTANGLE 4 5 我试图弄明白为什么strtok()循环不会取第二个“正方形”的末端,而只是将长度设为0。我也不完全理解strtok背后的概念,我不介意一个关于strtok的讲座。代码如下: #include <cstring> #include <cstdlib> #include <iostream> using std::cout; using std::endl; using std:

以下是文本文件的内容:

SQUARE 2
SQUARE
RECTANGLE 4 5
我试图弄明白为什么strtok()循环不会取第二个“正方形”的末端,而只是将长度设为0。我也不完全理解strtok背后的概念,我不介意一个关于strtok的讲座。代码如下:

#include <cstring>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::ios;

#include<iomanip>
using std::setprecision;

#include <fstream>
using std::ifstream;

const int MAX_CHARS_PER_LINE = 512;
const int MAX_TOKENS_PER_LINE = 20;
const char* const DELIMITER = " ";

int main()
{
// create a file-reading object
ifstream fin;
fin.open("geo.txt"); // open a file
if (!fin.good()) 
    return 1; // exit if file not found

//PI
float pi = 3.14159265359; 

//DIMENSIONS
float length, width, height, radius;

//AREAS, PERIMETERS, VOLUMES
float areaSquare, periSquare;
float areaRectangle, periRectangle;
float areaCube, volCube;
float areaPrism, volPrism;
float areaCircle, periCircle;
float areaCylinder, volCylinder;

// read each line of the file
while (!fin.eof())
{
    // read an entire line into memory
    char buf[MAX_CHARS_PER_LINE];
    fin.getline(buf, MAX_CHARS_PER_LINE);
    // parse the line into blank-delimited tokens
    int n = 0; // a for-loop index

    // array to store memory addresses of the tokens in buf
    const char* token[MAX_TOKENS_PER_LINE] = {0}; // initialize to 0

    // parse the line
    token[0] = strtok(buf, DELIMITER); // first token
    if (token[0]) // zero if line is blank
    {
        for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
        {
            token[n] = strtok(0, DELIMITER); // subsequent tokens
            if (!token[n] || token[n]==0) break;
        }
    }

    if(strcmp("SQUARE", token[0]) == 0) //1
    {
        length = atof(token[1])?atof(token[1]):0;
        areaSquare = length * length;
        periSquare = 4 * length;

        cout.setf(ios::fixed|ios::showpoint);
        cout << setprecision(2);
        cout << token[0] << ' ' << "length="<< token[1] << ' ';
        cout << "Area=" << areaSquare << ' ';
        cout << "Perimeter=" << periSquare << '\n';
        cout.unsetf(ios::fixed|ios::showpoint);
        cout << setprecision(6);
    }

    else if(strcmp("RECTANGLE", token[0]) == 0) //2
    {
        length = atof(token[1])?atof(token[1]):0;
        width = atof(token[2])?atof(token[2]):0;

        areaRectangle = length * width;
        periRectangle = 2 * length + 2 * width;

        cout.setf(ios::fixed|ios::showpoint);
        cout << setprecision(2);
        cout << token[0] << ' ' << "length="<< token[1] << ' ';
        cout << "width=" << token[2] << ' ' ;
        cout << "Area=" << areaRectangle << ' ';
        cout << "Perimeter=" << periRectangle << '\n';
        cout.unsetf(ios::fixed|ios::showpoint);
        cout << setprecision(6);
        }
    else
    {
        cout << "End of program. Press ENTER to exit.";
        cin.ignore(1000,10);
        break;
}
    }
}
#包括
#包括
#包括
使用std::cout;
使用std::endl;
使用std::cin;
使用std::ios;
#包括
使用std::setprecision;
#包括
使用std::ifstream;
每行最大字符数=512;
const int MAX_TOKENS_PER_LINE=20;
常量字符*常量分隔符=”;
int main()
{
//创建文件读取对象
流鳍;
fin.open(“geo.txt”);//打开文件
如果(!fin.good())
返回1;//如果找不到文件,则退出
//圆周率
浮点数pi=3.14159265359;
//尺寸
浮动长度、宽度、高度、半径;
//面积、周长、体积
浮动区域正方形、方正方形;
浮动区域矩形、周边矩形;
float-areaCube,volCube;
浮动区域棱镜、旋转棱镜;
浮动区域圆、圆周;
浮缸、浮缸;
//读取文件的每一行
而(!fin.eof())
{
//把一整行读入内存
char buf[每行最大字符数];
fin.getline(buf,每行最大字符数);
//将行解析为空白分隔标记
int n=0;//一个for循环索引
//用于在buf中存储令牌的内存地址的数组
const char*token[MAX_TOKENS_PER_LINE]={0};//初始化为0
//解析行
令牌[0]=strtok(buf,分隔符);//第一个令牌
if(标记[0])//如果行为空,则为零
{
对于(n=1;ncout这是一个有效的版本

主要区别是,

  • 已将char*的数组更改为20个char字符串的数组。这保证数组元素已分配内存,在您的情况下,它们是空指针,并且在strtok返回空时保持这种状态,因此不能使用空指针
  • 对strtok的第二个调用是“strtok(0,分隔符)” 但是应该是“strtok(NULL,分隔符)”
  • 我认为它们是唯一的差异,但请使用差异实用程序进行检查

    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::cin;
    using std::ios;
    
    #include<iomanip>
    using std::setprecision;
    
    #include <fstream>
    using std::ifstream;
    
    const int MAX_CHARS_PER_LINE = 512;
    const int MAX_TOKENS_PER_LINE = 20;
    const char* const DELIMITER = " ";
    
    int main()
    {
    // create a file-reading object
       char *tok;
       ifstream fin;
       fin.open("geo.txt"); // open a file
       if (!fin.good())
           return 1; // exit if file not found
    
           //PI
           float pi = 3.14159265359;
    
           //DIMENSIONS
           float length, width, height, radius;
    
           //AREAS, PERIMETERS, VOLUMES
           float areaSquare, periSquare;
           float areaRectangle, periRectangle;
           float areaCube, volCube;
           float areaPrism, volPrism;
           float areaCircle, periCircle;
           float areaCylinder, volCylinder;
    
           // read each line of the file
           while (!fin.eof())
           {
               // read an entire line into memory
               char buf[MAX_CHARS_PER_LINE];
               fin.getline(buf, MAX_CHARS_PER_LINE);
               // parse the line into blank-delimited tokens
               int n = 0; // a for-loop index
    
               // array to store memory addresses of the tokens in buf
    //         const char* token[MAX_TOKENS_PER_LINE] = {0}; // initialize to 0
               char token[MAX_TOKENS_PER_LINE][20];
               for (n=0;n<MAX_TOKENS_PER_LINE;n++)
                   {
                   token[n][0] = NULL;
                   }
               // parse the line
               tok = strtok(buf, DELIMITER); // first token
               if (tok == NULL)
                   break;
               strcpy(token[0],tok);
               if (token[0]) // zero if line is blank
                   {
                   for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
                       {
                       tok = strtok(NULL, DELIMITER); // subsequent tokens
                       if (tok == NULL)
                           break;
                       strcpy(token[n],tok);
    //                 if (!token[n] || token[n]==0) break;
                       }
                   }
               if(strcmp("SQUARE", token[0]) == 0) //1
                    {
                    length = atof(token[1])?atof(token[1]):0;
                    areaSquare = length * length;
                    periSquare = 4 * length;
    
                    cout.setf(ios::fixed|ios::showpoint);
                    cout << setprecision(2);
                    cout << token[0] << ' ' << "length="<< token[1] << ' ';
                    cout << "Area=" << areaSquare << ' ';
                    cout << "Perimeter=" << periSquare << '\n';
                    cout.unsetf(ios::fixed|ios::showpoint);
                    cout << setprecision(6);
                    }
    
                else if(strcmp("RECTANGLE", token[0]) == 0) //2
                    {
                    length = atof(token[1])?atof(token[1]):0;
                    width = atof(token[2])?atof(token[2]):0;
    
                    areaRectangle = length * width;
                    periRectangle = 2 * length + 2 * width;
    
                    cout.setf(ios::fixed|ios::showpoint);
                    cout << setprecision(2);
                    cout << token[0] << ' ' << "length="<< token[1] << ' ';
                    cout << "width=" << token[2] << ' ' ;
                    cout << "Area=" << areaRectangle << ' ';
                    cout << "Perimeter=" << periRectangle << '\n';
                    cout.unsetf(ios::fixed|ios::showpoint);
                    cout << setprecision(6);
                }
            else
                {
                cout << "End of program. Press ENTER to exit.";
                cin.ignore(1000,10);
                break;
                }
            }
    }
    
    #包括
    #包括
    #包括
    使用std::cout;
    使用std::endl;
    使用std::cin;
    使用std::ios;
    #包括
    使用std::setprecision;
    #包括
    使用std::ifstream;
    每行最大字符数=512;
    const int MAX_TOKENS_PER_LINE=20;
    常量字符*常量分隔符=”;
    int main()
    {
    //创建文件读取对象
    char*tok;
    流鳍;
    fin.open(“geo.txt”);//打开文件
    如果(!fin.good())
    返回1;//如果找不到文件,则退出
    //圆周率
    浮点数pi=3.14159265359;
    //尺寸
    浮动长度、宽度、高度、半径;
    //面积、周长、体积
    浮动区域正方形、方正方形;
    浮动区域矩形、周边矩形;
    float-areaCube,volCube;
    浮动区域棱镜、旋转棱镜;
    浮动区域圆、圆周;
    浮缸、浮缸;
    //读取文件的每一行
    而(!fin.eof())
    {
    //把一整行读入内存
    char buf[每行最大字符数];
    fin.getline(buf,每行最大字符数);
    //将行解析为空白分隔标记
    int n=0;//一个for循环索引
    //用于在buf中存储令牌的内存地址的数组
    //const char*token[MAX_TOKENS_PER_LINE]={0};//初始化为0
    字符令牌[每行最大令牌数][20];
    
    对于(n=0;n,这里有一个有效的版本

    主要区别是,

  • 已将char*的数组更改为20个char字符串的数组。这保证数组元素已分配内存,在您的情况下,它们是空指针,并且在strtok返回空时保持这种状态,因此不能使用空指针
  • 对strtok的第二个调用是“strtok(0,分隔符)” 但是应该是“strtok(NULL,分隔符)”
  • 我认为它们是唯一的差异,但请使用差异实用程序进行检查

    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::cin;
    using std::ios;
    
    #include<iomanip>
    using std::setprecision;
    
    #include <fstream>
    using std::ifstream;
    
    const int MAX_CHARS_PER_LINE = 512;
    const int MAX_TOKENS_PER_LINE = 20;
    const char* const DELIMITER = " ";
    
    int main()
    {
    // create a file-reading object
       char *tok;
       ifstream fin;
       fin.open("geo.txt"); // open a file
       if (!fin.good())
           return 1; // exit if file not found
    
           //PI
           float pi = 3.14159265359;
    
           //DIMENSIONS
           float length, width, height, radius;
    
           //AREAS, PERIMETERS, VOLUMES
           float areaSquare, periSquare;
           float areaRectangle, periRectangle;
           float areaCube, volCube;
           float areaPrism, volPrism;
           float areaCircle, periCircle;
           float areaCylinder, volCylinder;
    
           // read each line of the file
           while (!fin.eof())
           {
               // read an entire line into memory
               char buf[MAX_CHARS_PER_LINE];
               fin.getline(buf, MAX_CHARS_PER_LINE);
               // parse the line into blank-delimited tokens
               int n = 0; // a for-loop index
    
               // array to store memory addresses of the tokens in buf
    //         const char* token[MAX_TOKENS_PER_LINE] = {0}; // initialize to 0
               char token[MAX_TOKENS_PER_LINE][20];
               for (n=0;n<MAX_TOKENS_PER_LINE;n++)
                   {
                   token[n][0] = NULL;
                   }
               // parse the line
               tok = strtok(buf, DELIMITER); // first token
               if (tok == NULL)
                   break;
               strcpy(token[0],tok);
               if (token[0]) // zero if line is blank
                   {
                   for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
                       {
                       tok = strtok(NULL, DELIMITER); // subsequent tokens
                       if (tok == NULL)
                           break;
                       strcpy(token[n],tok);
    //                 if (!token[n] || token[n]==0) break;
                       }
                   }
               if(strcmp("SQUARE", token[0]) == 0) //1
                    {
                    length = atof(token[1])?atof(token[1]):0;
                    areaSquare = length * length;
                    periSquare = 4 * length;
    
                    cout.setf(ios::fixed|ios::showpoint);
                    cout << setprecision(2);
                    cout << token[0] << ' ' << "length="<< token[1] << ' ';
                    cout << "Area=" << areaSquare << ' ';
                    cout << "Perimeter=" << periSquare << '\n';
                    cout.unsetf(ios::fixed|ios::showpoint);
                    cout << setprecision(6);
                    }
    
                else if(strcmp("RECTANGLE", token[0]) == 0) //2
                    {
                    length = atof(token[1])?atof(token[1]):0;
                    width = atof(token[2])?atof(token[2]):0;
    
                    areaRectangle = length * width;
                    periRectangle = 2 * length + 2 * width;
    
                    cout.setf(ios::fixed|ios::showpoint);
                    cout << setprecision(2);
                    cout << token[0] << ' ' << "length="<< token[1] << ' ';
                    cout << "width=" << token[2] << ' ' ;
                    cout << "Area=" << areaRectangle << ' ';
                    cout << "Perimeter=" << periRectangle << '\n';
                    cout.unsetf(ios::fixed|ios::showpoint);
                    cout << setprecision(6);
                }
            else
                {
                cout << "End of program. Press ENTER to exit.";
                cin.ignore(1000,10);
                break;
                }
            }
    }
    
    #包括
    #包括
    #包括
    使用std::cout;
    使用std::endl;
    使用std::cin;
    使用std::ios;
    #包括
    使用std::setprecision;
    #包括
    使用std::ifstream;
    每行最大字符数=512;
    const int MAX_TOKENS_PER_LINE=20;
    常量字符*常量分隔符=”;
    int main()
    {
    //创建文件读取对象
    char*tok;
    流鳍;
    fin.open(“geo.txt”);//打开文件
    如果(!fin.good())
    返回1;//如果找不到文件,则退出
    //圆周率
    浮点数pi=3.14159265359;
    //尺寸
    浮动长度、宽度、高度、半径;
    //面积、周长、体积
    浮动区域正方形、方正方形;
    浮动区域矩形、周边矩形;
    float-areaCube,volCube;
    浮动区域棱镜、旋转棱镜;
    浮动区域圆、圆周;
    浮缸、浮缸;
    //读取文件的每一行
    而(!fin.eof())
    {
    //把一整行读入内存
    char buf[每行最大字符数];
    fin.getline(buf,每行最大字符数);
    //将行解析为空白分隔标记
    int n=0;//一个for循环索引
    //用于在buf中存储令牌的内存地址的数组
    //const char*token[MAX_TOKENS_PER_LINE]={0};//初始化为0
    字符令牌[每行最大令牌数][20];
    对于(n=0;n好的。当您的线路

    const char*token[MAX\u TOKENS\u PER\u LINE]={0};

    创建指针数组,但没有一个指针指向任何对象。第一个元素设置为0(为空地址),其余元素未初始化。运行并处理第2行(有1个元素)时,令牌[0]指向“SQUARE”,但令牌[1]的值为0x00(空)。这是无效的内存
    length = atof(token[1])?atof(token[1]):0;
    
    here are spaces0
    
    here0are0spaces0
    
    char *input_string;        // Just so we have it
    const int MAX_TOKENS = 10; // Arbitrary number
    char *tokens[MAX_TOKENS];  // This will do all the storage we need.
    tokens[0] = strtok(input_string, " -=\""); // Setup call.
    int number_of_tokens = 1;  // We've already filled tokens[0], so we have 1 token. We want to start filling from 1.
    
    do {
        if (tokens[number_of_tokens] = strtok(NULL," -=\"")) number_of_tokens++;
        else break;
    } while(number_of_tokens < MAX_TOKENS);
    
    *tokens[0]="here"
    *tokens[1]="are"
    *tokens[2]="some"
    *tokens[3]="words"
    *tokens[4] = NULL
    number_of_tokens = 4
    
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::cin;
    using std::ios;
    using std::cerr;
    
    #include<iomanip>
    using std::setprecision;
    
    #include <fstream>
    using std::ifstream;
    
    const int MAX_CHARS_PER_LINE = 512;
    const int MAX_TOKENS_PER_LINE = 20;
    const char* const DELIMITER = " ";
    
    int main()
    {
        // create a file-reading object
        const char *fname = "geo.txt";
        ifstream fin;
        fin.open(fname); // open a file
        if (!fin.good()) 
        {
            cerr << "Failed to open file " << fname << endl;;
            return 1; // exit if file not found
        }
    
        // read each line of the file
        char buf[MAX_CHARS_PER_LINE];
        while (fin.getline(buf, sizeof(buf)))
        {
            int n = 0;
            const char *token[MAX_TOKENS_PER_LINE] = {0};
            char *position = buf;
    
            while ((token[n] = strtok(position, DELIMITER)) != 0)
            {
                cout << "Token " << n << ": " << token[n] << endl;
                n++;
                position = 0;
            }
    
            if (strcmp("SQUARE", token[0]) == 0 && n == 2)
            {
                float length = atof(token[1])?atof(token[1]):0;
                float areaSquare = length * length;
                float periSquare = 4 * length;
                cout.setf(ios::fixed|ios::showpoint);
                cout << setprecision(2);
                cout << token[0] << ' ' << "length="<< token[1] << ' ';
                cout << "Area=" << areaSquare << ' ';
                cout << "Perimeter=" << periSquare << '\n';
                cout.unsetf(ios::fixed|ios::showpoint);
                cout << setprecision(6);
            }
            else if (strcmp("RECTANGLE", token[0]) == 0 && n == 3)
            {
                float length = atof(token[1])?atof(token[1]):0;
                float width = atof(token[2])?atof(token[2]):0;
                float areaRectangle = length * width;
                float periRectangle = 2 * length + 2 * width;
                cout.setf(ios::fixed|ios::showpoint);
                cout << setprecision(2);
                cout << token[0] << ' ' << "length="<< token[1] << ' ';
                cout << "width=" << token[2] << ' ' ;
                cout << "Area=" << areaRectangle << ' ';
                cout << "Perimeter=" << periRectangle << '\n';
                cout.unsetf(ios::fixed|ios::showpoint);
                cout << setprecision(6);
            }
            else
            {
                cout << "Unrecognized data: " << buf << endl;
            }
        }
    }