关于命令行参数/ char *的三个问题

时间:2014-05-14 04:34:44

标签: c++ c++11

我的帖子分为三个部分:

1. My code
2. Example input and output
3. My three questions

我的代码:

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cstring>

using namespace std;

void deleteTrash(char*, char*);

const int kStr = 2;
const int kStrLen = 3;

int main(int argc, char* argv[])
{
    if (argc < 4) {
        cout << "Incorrect argument given." << endl;
        cout << "Try again." << endl;
        return 0;
    }

    cout << "PRINT argv[2]" << endl;
    cout << "-----" << endl;
    for (int i = 0; i < sizeof(argv[2]); i++) {
       cout << "Iterator: " << i << endl;
       cout << argv[2][i] << endl;
    }

    char* inputString;
    deleteTrash(argv[kStr], inputString);

    cout << "PRINT inputString" << endl;
    cout << "-----" << endl;
    for (int i = 0; i < sizeof(inputString); i++) {
        cout << i << endl;
        cout << inputString[i] << endl;
    }

    int strLen;
    stringstream num;
    num << argv[kStrLen];
    num >> strLen;

    if ( num.fail() ) {
        cout << "Incorrect argument given." << endl;
        cout << "Try again." << endl;
        return 0;
    }

    if ( strLen < sizeof(inputString) ) {
        cout << "Incorrect argument given." << endl;
        cout << "Try again." << endl;
        return 0;
    }

    return 0;
}

void deleteTrash(char* tempString, char* inputString) 
{
    int tempStringLen = sizeof(tempString);
    int newSize = 0;

    while (tempString[newSize] != '\0')
        newSize++;

    char newString[newSize + 1];

    int iterator = 0;

    while (tempString[iterator] != '\0') {
        newString[iterator] = tempString[iterator];
        iterator++;
    }

    newString[newSize] = '\0';

    cout << "PRINT newString" << endl;
    cout << "-----" << endl;
    for (int i = 0; i < sizeof(newString); i++) {
        cout << newString[i] << endl;
    }   

    inputString = newString;

    cout << "PRINT inputString" << endl;
    cout << "-----" << endl;
    for (int i = 0; i < sizeof(inputString); i++) {
        cout << "Iterator: " << i << endl;
        cout << inputString[i] << endl;
    }   

    return;
}

示例输入:

./hw1q5 4 W# 3

输出:

PRINT argv[2]
-----
Iterator: 0
W
Iterator: 1
#
Iterator: 2

Iterator: 3
3
Iterator: 4

Iterator: 5
T
Iterator: 6
E
Iterator: 7
R
PRINT newString
-----
W
#

PRINT inputString
-----
Iterator: 0
W
Iterator: 1
#
Iterator: 2

Iterator: 3

Iterator: 4

Iterator: 5

Iterator: 6

Iterator: 7

PRINT inputString
-----
0
Segmentation fault: 11

我的问题:

  1. 为什么argv包含3个以上的元素(M,#和\ 0)。它打印出8个元素(print语句迭代0 - 7),在W之后,#,\ 0是垃圾。它不应该只打印3个元素(M,#和\ 0)。为什么会这样?我该如何解决?
  2. 为什么当我将newString(type char)设置为inputString(type char *)时,通过执行inputString = newString,inputString在print语句中迭代8次,在打印M,#和\ 0后打印空白。
  3. 为什么seg错误发生在第三个声明中?

3 个答案:

答案 0 :(得分:3)

sizeof()不返回以null结尾的字符数组字符串的长度。相反,你需要像strlen()这样的东西。

答案 1 :(得分:2)

让我们在这里解决其中一个问题:

// Wrong!
int main(int argc, char* argv[])
...
for (int i = 0; i < sizeof(argv[2]); i++) {
   cout << "Iterator: " << i << endl;
   cout << argv[2][i] << endl;
}

// Better
int main(int argc, char* argv[])
...
for (int i = 0; i < argc; i++) {
   cout << "argv[" << i << "]: " << argv[i] << endl;
}

argv []是一个或多个&#34; C&#34;字符串。

argc告诉你数组中有多少个字符串。

您希望迭代数组中的字符串(argv [i]),而不是字符串中的字符(例如,&#34; argv [0] [0]&#34;)。

......和......

&#34;的sizeof(argv的)&#34;只给你一个指针的大小(4个字节,对于一个32位CPU)。它 NOT 为您提供数组中的#/元素。那是&#34; argc&#34;是为了。

答案 2 :(得分:0)

在回答您的第一个问题时,我将向您推荐另一篇SO文章:What does int argc, char *argv[] mean?

第一个命令行参数始终是命令本身。所以在你的例子中:

./hw1q5 4 W# 3

有四个命令行参数:hw1q5,4,W#和3.

关于你的其他问题,以及第一个问题的其余部分,你的大多数问题源于假设sizeof(char *)返回一个空终止字符串的长度,它没有(就像在评论和早期答案中都指出了这一点。

理解sizeof的一个很好的参考资料可以在这里找到:http://en.cppreference.com/w/cpp/language/sizeof,或者我怀疑这是一个基于你编译的程序名称,C ++教科书的家庭作业。