首页 > 解决方案 > 将字符串转换为 char *var[]

问题描述

尝试在cpp中做点什么,好久没用了,需要把字符串解析成char *var[]。我似乎无法弄清楚。我目前的尝试是使用字符串流并以这种方式输入,但我得到了一个错误的EXC_BAD_ACC。我能够发现关于该错误的信息是我正在将信息发送到某个地方并且它无法对它做任何事情。我做错了什么,应该怎么做?

#include<iostream>
#include<unistd.h>
#include <stdio.h>
#include <string.h>
#include <sstream>
#define MAXLINE 80
using namespace std;


int main(int argc, char *argv[]){
    char *args[MAXLINE/2+1];
    bool ShouldRun = true;
    string hello;
    while(ShouldRun)
    {
        cout << "osh>";
        fflush(stdout);
        cin >> hello;
        int i = 0;

        stringstream ssin(hello);
        while(ssin.good() && 41){
            ssin >> args[i]; //errors here.
            ++i;
        }
    }
    return 0;
}

标签: c++

解决方案


“我用 strcpy 试过那个方法,它说不char*兼容char**

这个错误很能说明问题。在您的代码中,您声明args为:

char *args[MAXLINE/2+1];

这没有声明一个字符数组,它声明了一个指向它们的指针 char数组MAXLINE/2+1

现在,无论您想要一个简单的 c 字符串还是想要一个它们的数组,您的代码都有些模棱两可。Given #define MAXLINE 80,并且您对它的检查41似乎只是想要一个 c-string 而不是 c-strings 数组。在这种情况下,您只需将声明更改为:

char args[MAXLINE/2+1];

这将创建一个41 字节的数组, char其中最多可存储 40 个字符(加上nul 终止字符)。要转换hello为 c 字符串,您只需要使用.c_str()成员函数。(请参阅cppreference.com - c_str)您需要首先验证它是否适合您可以使用的hello.length().

把它放在一起,你可以这样做:

#include <iostream>
#include <string>
#include <cstring>

#define MAXLINE 80

using namespace std;

int main (void) {

    char args[MAXLINE/2+1];     /* array of char - not pointers */
    bool ShouldRun = true;
    string hello;

    while(ShouldRun)
    {
        cout << "osh> ";
        if (!(cin >> hello))
            break;

        if (hello.length() <= MAXLINE/2) {  /* validate length of hello */
            strcpy (args, hello.c_str());       /* copy to args */
            cout << "args: " << args << '\n';   /* output args */
        }
    }
    return 0;
}

示例使用/输出

$ ./bin/string2c_str
osh> first_arg
args: first_arg
osh> second_arg
args: second_arg
osh> 

如果要将所有输入作为单独的 c 字符串存储在指针数组中,则需要args[i]在复制到每个输入之前分配存储空间并为其分配起始地址,或者声明args为固定大小的二维数组。让我知道这是否是您正在尝试的。

使用指向 Char 的指针数组

execvp按照您的评论中指示使用,那么args确实需要一个指针数组,指向 char您最后一个参数之后的下一个指针必须显式设置NULL以指示参数结束的位置。

MAXLINE/2您还必须确保您填写的指针不超过最后显式设置的指针NULL。您可以通过初始化设置所有指针NULL,然后hello.length() + 1为每个字符串分配存储字符,args[i]在将 c 字符串复制到该地址之前分配新块的起始地址。

把这个例子放在一起,你会得到:

#include <string>
#include <cstring>

#define MAXLINE 80

using namespace std;

int main (void) {

    char *args[MAXLINE/2+1] = {nullptr};    /* array of pointers to char */
    bool ShouldRun = true;
    int n = 0;
    string hello;

    while(ShouldRun)
    {
        cout << "osh> ";
        if (n == MAXLINE/2 || !(cin >> hello)) {    /* protect bounds */
            cout << '\n';
            break;
        }

        args[n] = new char [hello.length() + 1];    /* allocate storage */
        strcpy (args[n++], hello.c_str());          /* copy to args[n] */
    }

    n = 0;
    while (args[n]) {           /* output args until NULL encountered */
        cout << "args[" << n << "]: " << args[n] << '\n';
        delete[] args[n++];     /* don't forget to free what you allocate */
    }

    return 0;
}

注意:EOF通过Ctrl+c在 Linux 上生成手册(或Ctrl+zWindows 上的 ),将存储参数直到读取循环退出))

示例使用/输出

$ ./bin/string2c_str_array
osh> arg_1
osh> arg_2
osh> arg_3
osh>
args[0]: arg_1
args[1]: arg_2
args[2]: arg_3

推荐阅读