尝试在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;
}
答案 0 :(得分:2)
“我用strcpy尝试了该方法,它说
char*
与char**
不兼容”
该错误表明。在代码中,您将args
声明为:
char *args[MAXLINE/2+1];
没有声明字符数组,而是声明了指向{em> char
,其中MAXLINE/2+1
的指针的数组。
现在,无论您是想要简单的c字符串还是想要它们的数组,您的代码都有些含糊。给定#define MAXLINE 80
,然后对41
进行检查,您似乎只需要一个c字符串而不是一个c字符串数组。在这种情况下,您只需要将声明更改为:
char args[MAXLINE/2+1];
这将创建一个41字节的 {em> 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
或声明{{ 1}}作为固定大小的2D数组。让我知道您是否正在尝试这种方法。
使用指向Char的指针数组
要按照您的注释中的说明使用execvp
,那么args
实际上确实需要一个指针数组 char
,其中您的下一个指针必须将最后一个参数明确设置为NULL
,以指示参数结束。
还必须确保填充不超过MAXLINE/2
个指针,而保留最后一个显式设置的NULL
。您可以通过初始化设置所有指针NULL
,然后为每个字符串分配hello.length() + 1
个存储字符,在将c字符串复制到args[i]
之前,将新块的起始地址分配给#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
(注意:,在Linux(或)上使用 Ctrl + c 生成手册$ ./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
来存储参数,直到读取循环退出为止在Windows上为Ctrl + z ))
使用/输出示例
mPlayer.addListener(object : IPlayerEventListener {
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
super.onPlayerStateChanged(playWhenReady, playbackState)
if (playbackState == Player.STATE_READY) {
// Apply some logic here whenever you want to get the duration
var durationMillis = mPlayer.getDuration()
// Apply some logic here to send out the data to your servers (whether after video paused, resumed, stopped, your choice)
// Example (Assuming you use MVVM + RxJava + Retrofit, this is a common way to do network call)
viewModel.uploadPlaybackDetails(userId = 21, videoId = 18, playbackTime = durationMillis)
}
}
override fun onPlayerError(error: ExoPlaybackException?) {
super.onPlayerError(error)
// Handle error here
}
})