c++ - C++ 我需要了解在哪里使用指针和双指针
问题描述
我有这个基本的多功能工具程序,其目标是在一个包含一些字符串的文件上完成四个功能。例如,取一个字符串,取一行并将其放入大写。我知道它还不完美,但我需要了解为什么我的 char* 和 char** 会搞得一团糟。
非常感谢您的时间
#include <iostream> //to use enter and exit
#include <cstring>
#include <string>
#include <fstream> //to use files
using namespace std;
/*--------------------------FONCTION PART-----------------------------------*/
//define one fonction for each transformation
//FONCTION 1
void fonctionu (char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern);
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
if(line[i] >= 'a' && line[i] <= 'z') {
line[i] = line[i] - (32);// (ASCII)
cout<<line[i];
}} }
if (found == string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<<line[i];
}}}}}
//FONCTION 2
void fonctiond( char* argv){ //remove line with xyz
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern); //as a reminder argv[2] is the pattern (warning : it need to be an unsigned to compare two unsigned)
if (found != string::npos) {
//delete the line of the file when there is the pattern
cout<<'\0'; }
if (found == string::npos){
for (int i = 0; line[i]!='\0'; i++) {
cout<< line[i];
}}}}}
//FONCTION 3
void fonctionc( char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data ){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern); //as a reminder argv[2] is the pattern
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<< "\033[31m"<< line[i]; //the line will be red
}
}
if (found == string::npos){
for (int i = 0; line[i]!='\0'; i++) {
cout<< line[i];
}}}}}
//FONCTION 4
//replace the pattern xyz by abc
void fonctions ( char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data ){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern);
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
if(line[i] >= 'a' && line[i] <= 'z') {
line[i] = line[i] - (97); // (ASCII) //we creat a shift that allow to make the x became a 'a' and the y a 'b'...etc
cout<<line[i];}}
}
if (found == string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<<line[i];
}}}}}
/*--------------------------MAIN PART---------------------------------------*/
int main(char* argv){
// ipsacs : argv[0]
//option :
string a = argv[1]; //string ! to compare line 103,108 and 112
// pattern : argv[2];
//file : argv[3];
if (argv[1]=='\0' || argv[2]=='\0'){
cout <<"ERROR"<<'\n';}
if (a == "u"){
char fonctionu (argv);}
if (a== "d"){
char fonctiond(argv);}
if (a == "c"){
char fonctionc(argv);}
if (a == "s"){
char fonctions(argv);}
return 0;
}
/*--------------------------TEST PART--------------------------------------*/
/*
pour compiler : g++ -Wall ipsacs.cpp -o ipsacs
./ipsacs u xyz foo //how the program would receive arguments, basically
Le programme ne renvoie rien.
*/
这是编译日志:
main.cpp:22:30: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctiond(char*)’:
main.cpp:46:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctionc(char*)’:
main.cpp:66:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctions(char*)’:
main.cpp:88:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: At global scope:
main.cpp:109:5: warning: first argument of ‘int main(char*)’ should be ‘int’ [-Wmain]
int main(char* argv){
^~~~
main.cpp:109:5: warning: ‘int main(char*)’ takes only zero or two arguments [-Wmain]
main.cpp: In function ‘int main(char*)’:
main.cpp:113:20: error: conversion from ‘char’ to non-scalar type ‘std::string {aka std::basic_string}’ requested
string a = argv[1]; //string ! to compare line 103,108 and 112
~~~~~~^
main.cpp:121:26: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctionu (argv);}
^
main.cpp:123:25: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctiond(argv);}
^
main.cpp:125:27: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctionc(argv);}
^
main.cpp:127:27: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctions(argv);}
^
解决方案
Achar *
是指向保存字符的内存地址的指针,通常用于 c 字符串。
Achar **
是指向内存地址的指针,该指针指向指向包含字符的内存地址的指针,通常用于 c 字符串数组。
你的main
签名如果不是一个有效的形式,因为没有任何形式main
只接受一个字符指针。您最有可能寻找的表格是int main( int argc, int **argv )
. 这需要两个参数:argc
传递给程序的参数数量,以及argv
包含传递给程序的 c 字符串形式的参数。
在 main 方法中,您通常会确保它是正确的,即您将正确数量的参数传递给您的函数(注意:程序名称argc
始终至少为 1 )。argv[0]
std::string a = argv[1]
没问题,它会导致指向的字符串argv
转换为字符串。调用函数时,您有char functionu(argv);
. 您将char
要从该行中删除;实际上,按照它的编写方式,您正在尝试创建一个char
名为的变量functionu
,其初始值为argv
.
你的每个函数,而不是接受 achar *
应该接受 a char **
,然后当你有类似的东西时char file = argv[3];
,你会想把它改成char *file = argv[3];
,或者std::string file = argv[3];