【问题标题】:Splitting char array拆分字符数组
【发布时间】:2014-12-05 22:51:25
【问题描述】:

我有一个 char **names 数组,它基本上存储文件中的名称。

这是我的.txt 文件

Mike, Sam, Stuart
Andre, Williams, Phillips
Patels, Khan, Smith

基本上,我想在, 字符之前拆分和存储名称。 例如,Mike, Sam, Stuart 将变为...

newName[0] = Mike
newName[1] = Sam
newName[2] = Stuart

我有这样的事情......

for (int i=0; i<3; i++)
{
  for (int j=60, j>0; j--)
  {
     if(names[i][j] == ',')
     {
        cout << j << endl; //THIS PRINTS OUT THE POSITION. HOW CAN I STORE THE POSITION AND DO SOMETHING?
     }
  }
}

如果有人可以帮助我编写代码,我将不胜感激,这是正确的方向。我不想使用任何vectors

我已尝试存储这些学生的分数,但我想将其添加到 double *marks[2] 数组中。

这是我的.txt 文件...

69.9, 56.5
29.8, 20.0
35.6, 45.0

这是我的代码...

char **values;
char * pch;
pch = strtok (values[i], " ,");
while (pch != NULL)
{
    sscanf(pch, "%f, %f", &marks[i][0], &marks[i][1]);
    pch = strtok (NULL, " ,");
}

我得到随机值,例如 1.28277e-3071.96471e+257

【问题讨论】:

  • 为什么不使用 std::string 代替字符数组?
  • double *marks[2] : 指针??
  • @BLUEPIXY,是的,我想将标记存储到指针数组中。我需要一些帮助
  • 为什么是指针?为什么2
  • @BLUEPIXY 为每个数组存储 2 标记。例如,marks[0] = 69.9, 56.5marks[1] = 29.8, 20.0marks[2] = 35.6, 45.0

标签: c++ arrays char


【解决方案1】:

查找 strtok 命令,它对你很有帮助。

此代码查找连字符并打印内容...将其更改为逗号

#include <string.h>
#include <stdio.h>

int main()
{
   const char str[80] = "This is - www.tutorialspoint.com - website";
   const char s[2] = "-";

   char * newName[100]; /* at most 100 names */
   int iCurName = 0;


   char *token;

   /* get the first token */
   token = strtok(str, s);

   /* walk through other tokens */
   while( token != NULL ) 
   {
      printf( " %s\n", token );
      newName[iCurName] = malloc (char *) (strlen(token) + 1);
      strcpy(newName[iCurName],token);
      iCurrName ++;

      token = strtok(NULL, s);
   }

   return(0);
}

【讨论】:

  • 谢谢,在我的情况下,如何将拆分的字符存储到新数组中。例如,newName[0] = MikenewName[1] = SamnewName[2] = Stuart
  • 更改答案以回答您的问题
  • 差不多的东西。
  • @StuUser 要使用名称填充 newName 数组,您可以使用 strcpy_s() function #include #include int main( void ) { char string[80] ; // 使用 strcpy_s 和 strcat_s 的模板版本: strcpy_s( string, "Hello world from " ); strcat_s(字符串,“strcpy_s”); strcat_s(字符串,“和”); // 当然,如果我们愿意,我们可以明确提供大小: strcat_s( string, _countof(string), "strcat_s!" ); printf("字符串 = %s\n", 字符串); }
【解决方案2】:

使用函数strtok() 将输入行拆分为标记;使用strcpy_s() 将每个令牌复制到名称缓冲区中。

注意1strtok()函数将每个分隔符替换为'\0'字符,所以line变量不能用const声明。如果您的输入缓冲区必须保持不变,例如,如果您想将整行用于其他内容,请在调用 strtok() 函数之前对其进行复制。

注意 2:除了分割输入行之外,您可能还需要修剪空间。

#define MAX_LINE_LENGTH 80
#define MAX_NAME_LENGTH 20
#define MAX_NAMES_PER_LINE 3

const char constInput = "Mike, Sam, Stewart";
char line[MAX_LINE_LENGTH];
strcpy_s(line, MAX_LINE_LENGTH, constInput);

char *separator = ",";

char newName[MAX_NAMES_PER_LINE][MAX_NAME_LENGTH];
int i = 0;
char *token = strtok(line, separator);
while ((i < MAX_NAMES_PER_LINE) && ((token = strtok(NULL, separator)) != NULL))
{
    strcpy_s(newName[i++], MAX_NAME_LENGTH, token);
}

【讨论】:

  • 如果我想存储小数怎么办?例如,{(5.6, 9.0), (4.5, 9.0), (8.9, 2.0)}?
  • 要将字符串转换为小数,可以使用不同的字符串转换函数,例如atof或sscanf。
  • 感谢atof 功能。感谢您的回复,我已尝试将一些数值(请参阅顶部的已编辑帖子)存储到 double 数组中,但我遇到了一些困难。基本上,对于每一行,我都想将两个值存储到同一个数组中,即 (marks[0][0] = 56.9, marks[0][1] = 45.6), (marks[1][0] = 16.9, marks[1][1] = 15.6)
  • @StuUser,您在已编辑帖子的最后一个代码部分正确使用了 strtok,但是您将值解析为标记的方式不正确。尝试 sscanf(values[i], "%f, %f", &marks[i][0], &marks[i][1]);其中 values[i] 是一行标记,例如 "5.6, 9.0"
  • 谢谢,但我现在得到的是随机值,例如 1.28277e-3071.96471e+257
【解决方案3】:
char newName[3][60];

for (int i=0; i<3; i++){
    int r=0, c=0;
    for (int j=0; j<60; j++){
        if(names[i][j] == ',' || names[i][j] == '\0'){
            newName[r++][c] = '\0';
            c = 0;
            if(names[i][j] == '\0'){
                cout << newName[0] << '\n'
                     << newName[1] << '\n'
                     << newName[2] << '\n' << endl;
                break;
            }
            while(names[i][++j] == ' ')
                ;
            --j;
        } else {
            newName[r][c++] = names[i][j];
        }
    }
}

#include <fstream>
#include <iostream>

using namespace std;

int main() {
    ifstream inf("data.txt");
    double marks[2];
    char ch;

    while(inf.good()){
        inf >> marks[0] >> ch >> marks[1];
        cout << "mark1:"  << marks[0] << endl;
        cout << "mark2:"  << marks[1] << endl;
    }
}

【讨论】:

  • 如果我想存储小数怎么办?例如,{(5.6, 9.0), (4.5, 9.0), (8.9, 2.0)}?
  • @StuUser 如果偶数比它存储为字符串一样。但从文件中读取数值似乎很容易。
  • 感谢您的回复,我已尝试将一些数值(请参阅顶部的已编辑帖子)存储到 double 数组中,但我遇到了一些困难。基本上,对于每一行,我都想将两个值存储到同一个数组中,即 (marks[0][0] = 56.9, marks[0][1] = 45.6), (marks[1][0] = 16.9, marks[1][1] = 15.6)
  • 谢谢,请在我的问题中帮助我编辑我的代码。基本上,我想将这些值添加到相同的 marks[i][0]marks[i][1] 数组中,但是我的检查有些问题。
  • @StuUser 这将是你自己的。我已经展示了足够的样本。
【解决方案4】:

我不知道这个功能是否足够快,但这里是:

char** split_quotes(char *input, char separator = ' ', bool keep_quotes = false)
{
    if (&input && input)
    {
        size_t length = strlen(input);
        char **chunks = new char*[length];

        bool inQuotes = false;
        size_t count = 0, from = 0;

        for (size_t i = 0; i < length; i++)
        {
            if (input[i] == '"')
            {
                inQuotes = !inQuotes;
            }
            else if (input[i] == separator && !inQuotes)
            {
                size_t strlen = i - from;

                if (strlen > 0)
                {
                    if (!keep_quotes && input[from] == '"' && input[i - 1] == '"')
                    {
                        from++; strlen -= 2;
                    }

                    chunks[count] = new char[strlen + 1]();
                    strncpy(chunks[count], &input[from], strlen);
                    count++;
                }

                from = i + 1;
            }
        }

        if (from < length)
        {
            size_t strlen = length - from;

            if (!keep_quotes && input[from] == L'"' && input[length - 1] == L'"')
            {
                from++; strlen -= 2;
            }

            chunks[count] = new char[strlen + 1]();
            strncpy(chunks[count], &input[from], strlen);
            count++;
        }

        // Save chunks to result array //
        char **result = new char*[count + 1]();
        memcpy(result, chunks, sizeof(char*) * count);

        // free chunks //
        delete[] chunks;

        return result;
    }

    return NULL;
}

用法:

wchar_t **name = split_quotes(L"Mike,Donald,\"My Angel\",Anna", L',');
if (name)
{
    while (*name++)
    { 
        std::wcout << "Person: " << *name << std::endl;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    相关资源
    最近更新 更多