Тестирование C ++ для специальных символов в массиве cstring - PullRequest
1 голос
/ 06 апреля 2011

У меня есть массив строк C:

char test[6] = {'\n', 't', 'e', 's', 't', '\0'}

Я хочу проверить, начинается ли строка с символа пробела (\ n, \ t, \ r), и если да, переставить массивчтобы я переместил непробельные символы в начало массива и сократил cstring на 1 для каждого пробельного символа, который необходимо удалить.

Так что, если я начну со строки, которая выглядит следующим образом:

\n, \t, t, e, s, t, \0
or
\r, t, e, s, t, \0

после функции оба массива будут выглядеть так:

t, e, s, t, \0
t, e, s, t, \0

У меня две проблемы.Мой первый - мой условный тест для специальных символов, который не работает так, как должен

int idx = 0;
if (test[idx] != '\n' || test[idx] != '\r' || test[idx] != '\t')
    return;

Это вернется, даже если он действительно начинается с одного из этих специальных символов.

Однако этотакже, похоже, уже нуждается в серьезном улучшении.

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

По сути, я борюсь с логикой того, как это сделать.

Любая помощь очень ценится.Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 06 апреля 2011

Почему бы просто не увеличить указатель вперед, пока не будет найден непробельный символ?

char* cstr = test;
while (*cstr && (*cstr == '\n' || *cstr == '\r' || *cstr == '\t'))
    ++cstr;
2 голосов
/ 06 апреля 2011

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

Во-вторых, если вам нужно использовать char[] или действительно удалить пробелы, вам придется проделать гораздо больше работы. Если все, что вам нужно, это указатель на начало строки, это сделает жизнь намного проще. Символы все еще будут в памяти, но они не появятся в начале строки, если вы используете указатель.

char test[] = "\ntest";
char *test_ptr = test;
while (*test_ptr && isspace(*test_ptr)) {
    ++test_ptr;
}
/*test_ptr now points to the first non-whitespace character in test, or the NULL character at the end of the string if it was all whitespace.*/

Если вам нужна эта строка в начале самого массива char, вы можете использовать memmove после приведенного выше кода для сдвига строки (strcpy не будет работать, так как диапазоны перекрываются ):

/* to be placed after block of code above */
memmove(test, test_ptr, strlen(test)-(test_ptr-test)+1); /* +1 for NULL not automatically copied with memmove */
/* test[0] is now the first non-whitespace character or NULL */

Или, поскольку вы используете C ++, вы можете пойти по маршруту std::string:

std::string test = "\ntest";
size_t start_pos = test.find_first_not_of("\r\n\t");
if (start_pos != std::string::npos) {
    test = test.substr(start_pos, std::string::npos);
} else {
    test = "";
}
//test now contains no whitespace in the beginning
2 голосов
/ 06 апреля 2011

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

int idx = 0;
if (test[idx] != '\n' && test[idx] != '\r' && test[idx] != '\t')
    return;

Предполагая, что idx является индексом первого непробельного символа или нулевого терминатора, вы можете сократить строку следующим образом:

int i;
for (i = 0; test[idx+i] != '\0'; i++)
    test[i] = test[idx+i];
test[i] = '\0';

Как уже говорили другие, есть более элегантные способы сделать все это с помощью isspace() и указателей, но это должно дать вам основную идею.

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