функция ручного разделения в C - PullRequest
0 голосов
/ 18 мая 2011

Этот код ведет меня к стене.Цель - разделить на char [], используя запятую.Это работает в Java.Но выводит странный вывод в C. Я подозреваю, что ошибка на 28-й итерации цикла, где я пытался добавить 5, массив превращается в странные символы.

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

main()
{
    char asshat[] = {'4','5','5',',','7','4','7','\0'};

    int firstSize = 0;//
    int secondSize = 0;//

    //new = 4 \0 \0
    char first[] = {'0', '\0'};//
    //new = 
    char second[] = {'0', '\0'};//
    char *first_ptr = first;
    char *second_ptr = second;

    int takingFirst = 1;
    int takingSecond = 0;

    int i;
    for (i = 0; i < strlen(asshat); i++)
    {
        if (asshat[i] != ',')
        {
            if (takingFirst == 1)
            {
                first_ptr[firstSize] = asshat[i];//ERROR here when you add 5 you s**t bricks
                firstSize++;
                if (asshat[i+1] != ',')
                {
                    char new[firstSize+2];
                    int k;
                    for (k = 0; k < strlen(first_ptr); k++)
                    {
                        new[k] = first_ptr[k];
                    }
                    new[firstSize] = '0';
                    new[firstSize+1] = '\0';
                    first_ptr = new;
                }
            }
            if (takingSecond == 1)
            {
                second_ptr[secondSize] = asshat[i];
                secondSize++;
                if (asshat[i+1] != '\0')
                {
                    char new[secondSize+2];
                    int k;
                    for (k = 0; k < strlen(second_ptr); k++)
                    {
                        new[k] = second_ptr[k];
                    }
                    new[secondSize+1] = '\0';
                    second_ptr = new;
                }
            }
        }
        else
        {
            takingFirst = 0;
            takingSecond = 1;
        }
    }
    printf("%d\n",strlen(first_ptr));
    printf("%c%c%c\n",first_ptr[0],first_ptr[1],first_ptr[2]);
    printf("%s\n",first_ptr);

    printf("%d\n",strlen(second_ptr));
    printf("%c%c%c\n",second_ptr[0],second_ptr[1],second_ptr[2]);
    printf("%s\n",second_ptr);
}

Ответы [ 5 ]

2 голосов
/ 18 мая 2011

Вы объявляете new как локальную переменную и позволяете first_ptr указывать на область памяти этой локальной переменной:

{
    char new[firstSize+2];
    ...  
    first_ptr = new;
}

Тогда локальная переменная выходит из области видимости, и ее память будет использоваться повторнодругими переменными / ... созданными в будущем.first_ptr все еще указывает на эту область памяти, но массив, который там был, больше не существует.При попытке доступа к массиву через first_ptr может произойти все что угодно, и вы, скорее всего, найдете неожиданные значения.

0 голосов
/ 18 мая 2011

Я полагаю, вы пытаетесь скопировать "455" в first и "747" в second? Если это так, вы не выделили достаточно места для этого. char first[] = {'0', '\0'} выделяет только массив размером 2; вам понадобится 4. То же самое для second.

Вы пытаетесь решить слишком много задач на одном уровне, выясняя, где вы находитесь в исходной строке и , пытаетесь ли вы скопировать в first или second и отслеживание длины каждой подстроки; это усугубляет вашу путаницу и делает проблему более сложной, чем она должна быть.

Начните с разделения проблем: вам нужна одна функция, чтобы найти следующую подстроку в вашем вводе, и другая, чтобы скопировать эту подстроку в место назначения.

Честно говоря, лучший способ разбить строку - это использовать любую из стандартных библиотечных функций strtok, strchr или strcspn и использовать strcpy или strncpy для копирования подстроки. к массивам назначения. Есть много очень веских причин , а не , чтобы использовать strtok, но это один из самых простых способов сделать то, что вы ищете.

Вот общая процедура использования strtok:

char *token = strtok(asshat, ",");  // return a pointer to the substring
                                    // before the first comma
while (token)
{
  strcpy(destination[i++], token);   // assumes destination exists and is
                                     // large enough to hold the token contents
  token = strtok(NULL, ",");         // find the next substring in the sequence;
                                     // pass NULL to indicate you're continuing
                                     // in the same string
}

Как я упоминал выше, есть причины, по которым не хотите использовать strtok. Он изменяет входную строку (заменяет разделитель на 0), поэтому вы не можете использовать его для строкового литерала. Вы также можете сохранить исходную строку. Кроме того, strtok не является ни реентерабельным, ни поточно-ориентированным.

Применяя его к вашему конкретному случаю, вы можете сделать что-то вроде:

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

int main(void)
{
  char asshat[] = "455,747";
  char first[4] = "";
  char second[4] = "";
  char *destination[] = {first, second, NULL};
  size_t i = 0;

  char *token = strtok(asshat, ",");
  while (token && destination[i])  // continue while we get a token AND
  {                                // there's a place to save it
    strcpy(destination[i++], token);
    token = strtok(NULL, ",");
  }

  printf("first = %s\n", first);
  printf("second = %s\n", second);

  return 0;
}
0 голосов
/ 18 мая 2011

Чтобы разбить строку в C, я предлагаю вам оставить тяжелую работу для strtok () . Не изобретайте велосипед заново, если вам не нужно.

0 голосов
/ 18 мая 2011

Вы можете сделать это нарезкой примерно в одну строку:)

Предполагая, что есть хотя бы один , ...

char asshat[] = "hello,world";
char* second = asshat;
while (*second++ != ',');
*(second - 1) = 0;

printf("first: %s; second: %s\n",asshat,second);

Вы можете использовать это, чтобы проверить, есливообще есть запятая (она ужасно рухнет, если ее нет).

0 голосов
/ 18 мая 2011

Очень сложно прочитать, что делает ваше решение. Я попытался переопределить его, чтобы было проще при сохранении игры указателя:

#include <stdio.h>

int 
main(int argc, char *argv[])
{   
  /* Keeping variable names consistent :) */
  char asshat[] = "456,747";
  char *first = asshat, *second = asshat, *c = asshat;

  while (*c) {
    if (*c == ',') {
      *c = '\0'; second = ++c;
    } else c++;
  }   
  printf("first: %s\nsecond: %s\n", first, second);
  return 0;
}   

Это производит:

first: 456
second: 747
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...