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;n cout这是一个有效的版本
主要区别是,
已将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;
}
}
}