2016-10-18 5 views
1

Я пытаюсь найти, если два символа, следующие друг за другом, являются одним и тем же символом. т.е. если у меня есть этот вход «Старая женщина», я хочу напечатать рядом со вторым дубликатом D ». Вот мой код, но я не могу узнать, как это сделать. Вот мой код:C повторяющийся символ, символ по символу

void main() 
{ 
    char ch,ch2; 
    ch = getchar(); // getting the line of text 
    int i = 1; 
    ch2 = ch; 

    while (ch != '\n') // the loop will close if nothing entered 
    { 
     if (ch == ch2[&i]) { 
      printf("%c-duplicate", ch); 
     } 
     i++; 
     if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') { // checking for uppaercase vowel 
      printf("%c-upper case vowel", ch); 
     } 
     else if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') { // checking for lowecase vowel 
      printf("%c-lower case vowel", ch); 
     } 
     else if (ispunct(ch)) {   // checking for punctuation 
      printf("%c-punctuation", ch); 
     } 
     else 
      putchar(ch); 

      printf("\n"); 
      ch = getchar(); 
     } 
     printf("\n"); 
    } 
} 

Я устанавливаю символ в другую переменную, а затем проверяю их с помощью первого оператора if. Программа должна запускать символ по характеру.

+4

'ch2 [& i]' это неправильно во многих отношениях, либо 'ch2' не является массивом, ни' & i' действительным индексом. ('& i' - указатель, адрес памяти переменной' i'). Если 'ch2 = ch' сразу после' getch() 'call, и вы сравниваете их после, они всегда будут одинаковыми. –

+0

Подумайте о том, как инициализировать 'ch2', чтобы вы не выполнили тест' if (ch == ch2) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' (обратите внимание на мое тестовое предложение) –

+1

@BenceKaulics, но он компилируется чисто ... 'ch2 [& i]' используется так, как будто это 'i [ch2]', что, конечно же, не так. –

ответ

-1
  1. За другие предложения: Изменение ч == ch2 [& я] Это не имеет никакого смысла здесь
  2. Поскольку вы установили -СН = СН 2 перед циклом, то линия если (ч == ch2) (После вы его исправите) всегда будет оцениваться с точностью до первого раза
  3. Ваше другое, очень запутанное, если у вас есть несколько строк кода, вам нужно положить в скобки
  4. Имейте в виду, когда вы вводите свой вы фактически отправляете два символа, например («e» AND «\ n»), потому что вы нажимаете клавишу ввода после ввода символа и tha t counts
  5. Попробуйте немного сложнее, имея в виду сообщение об ошибке, приложите результаты ваших попыток к решению. Это помогает нам и вам. Это похоже на то, что вы написали это и сразу же хотите исправить. Программирование усложняется, если вы не можете работать через проблемы (с предложениями), тогда это будет больно намного больше, но это не обязательно.

Для быстрого грязного доказательства концепции добавьте еще один ch = getchar(); сразу после того, как под вашим другом. Обратите внимание, что приведенный ниже код должен выполняться, но не выполняет точно то, что вы хотите, вам нужно будет провести дополнительную отладку.

Редактировать 10/19/2016

Исправлена ​​ошибка char2 вы, ребята указали

Переехал CH2 = CH выше линий, которые получают новый характер

#include <stdio.h> 
#include <ctype.h> 

int main(){ 
    char ch,ch2; 
    ch = getchar(); // getting the line of text 
    int i = 1; 
    ch2 = 0; 

    while (ch != '\n') // the loop will close if nothing entered 
    { 
     if (ch == ch2) { 
      printf("%c-duplicate", ch); 
     } 
     i++; 
     if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') { // checking for uppaercase vowel 
      printf("%c-upper case vowel", ch); 
     } 
     else if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') { // checking for lowecase vowel 
      printf("%c-lower case vowel", ch); 
     } 
     else if (ispunct(ch)) {   // checking for punctuation 
      printf("%c-punctuation", ch); 
     } 

     printf("\n"); 
     ch2 = ch; 
     ch = getchar(); 
     ch = getchar(); 

    } 


    printf("\n"); 
    return 0; 
} 
+1

Получение ошибки, потому что в инструкции if ch2 не имеет значения –

+1

whoops. Я усвоил, как трудно компилировать примеры, которые вы публикуете. :) Инициализировать ch2 что-то вроде ch2 = 0; перед циклом. Только один ch = getchar(); я предполагаю. Получение ошибки о не инициализированной переменной - это возможность для обучения. :-) Вы получаете предупреждение или ошибку об этом? В зависимости от вашего компилятора c вы можете не получить предупреждение - я не (gcc 4.8.2). ch2 может быть инициализирован ко всему. Это var на стеке или в регистрах. – gaoithe

+0

Если я печатаю ch2, не инициализированный, я получаю 0x08 - символ табуляции. Если я передаю -Wall в gcc-компилятор, я получаю предупреждение «предупреждение:« ch2 »используется неинициализированным в этой функции [-Wuninitialized]» – gaoithe

1

Ниже приводится примером, который, как я считаю, является то, что вы намеревались. c - текущий символ, который считывается (примечание: это тип int), а c1 - это предыдущий символ, прочитанный (инициализирован -1, чтобы гарантировать, что он не соответствует первому тесту).

В то время как вы можете сравнить A и E ..., библиотека строк предоставляет strchr, что легко позволяет проверить, включен ли один символ в большую строку.

Вместо вызова printf для каждого duplicate или vowel и т.п .., почему бы не использовать sprintf построить строку, содержащую все критерии, применимые к любому одному символу. Таким образом, вы вызываете только printf один раз в конце каждой итерации (в зависимости от того, печатаете ли вы все или только те, которые соответствуют критериям). s используется в качестве буфера, который содержит информацию о совпадении для каждого символа, offset - это просто количество символов, ранее записанных на s.(вы должны проверить, чтобы вы не превышали количество символов, доступных в s (но это было ненужно здесь)

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

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

#define MAXL 32 

int main (int argc, char **argv) { 

    char *uvowel = "AEIOU", *lvowel = "aeiou"; 
    int c, c1 = -1; 

    while ((c = getchar()) != '\n' && c != EOF) { 
     char s[MAXL] = "";    /* description buffer */ 
     int offset = 0;     /* offset  */ 
     if (c == c1)     /* new == old */ 
      offset = sprintf (s, " duplicate"); 
     if (strchr (uvowel, c))   /* upper-case? */ 
      sprintf (s + offset, " upper-case vowel"); 
     else if (strchr (lvowel, c)) /* lower-case? */ 
      sprintf (s + offset, " lower-case vowel"); 
     else if (ispunct (c))   /* punctuation? */ 
      sprintf (s + offset, " punctuation"); 
     else if (argc > 1)    /* if printing all */ 
      sprintf (s + offset, " other"); 
     if (*s)       /* print c and s */ 
      printf (" %c - %s\n", c, s); 
     c1 = c;       /* save last char read */ 
    } 

    return 0; 
} 

Пример использования/выход

$ echo "The oldd woman" | ./bin/classdup 
e - lower-case vowel 
o - lower-case vowel 
d - duplicate 
o - lower-case vowel 
a - lower-case vowel 

Передайте любое значение в качестве первого аргумента для печати всех символов:

$ echo "The oldd woman" | ./bin/classdup 1 
T - other 
h - other 
e - lower-case vowel 
    - other 
o - lower-case vowel 
l - other 
d - other 
d - duplicate other 
    - other 
w - other 
o - lower-case vowel 
m - other 
a - lower-case vowel 
n - other 

Повторяющиеся гласные

$ echo "womaan" | ./bin/classdup 
o - lower-case vowel 
a - lower-case vowel 
a - duplicate lower-case vowel 

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

(примечание: вы хотите передать опцию -Wno-unused-parameter компилятора для устранения предупреждения о argv быть неиспользованными, или просто сделать тест-заглушку где-то в коде, например if (argv[1]) {})

+0

я получаю эти ошибки SEVERITY \t \t Код Описание \t \t Project File \t \t Line Подавление Государственный Ошибка \t \t C4996 'Sprintf': Эта функция или переменная может быть небезопасным. Вместо этого используйте sprintf_s. Чтобы отключить устаревание, используйте _CRT_SECURE_NO_WARNINGS. –

+1

Windows включает в себя предлагаемые '_s расширения для языка C (практически никто не делает). Предупреждение вызвано 'sprintf', позволяющим писать за пределами вашего массива, если вы не проверяете. Вы можете использовать 'snprintf', чтобы ограничить написанные символы (и сохранить переносимость кода). В этом случае ваша двойная проверка будет «snprintf (s, MAXL,« duplicate »)», а остальная часть будет «snprintf (s, MAXL-offset,« ..text ... »); windowism, но вы также можете использовать 'sprintf_s', если хотите. Примечание: параметры будут разными. –

+0

Чтобы устранить предупреждение, добавьте '#define _CRT_SECURE_NO_WARNINGS' в начало вашего кода. Вы столкнетесь с этим много, если будете кодировать в окнах. Это не значит, что код небезопасен. Microsoft довольно креативна в том, как она пытается привлечь людей к своим продуктам. Вы можете прочитать больше здесь [** Функции Microsoft _s, являются ли они частью стандарта C++ сейчас? **) (http://stackoverflow.com/questions/617571/microsoft-s-functions-are-they-part-of -The-с-стандарт-сейчас) –

1

Стоит отвечать, чтобы попытаться помочь понять переменные и указатели, я думаю.

Чтобы попытаться ответить. , , как можно проще. , , ПРИМЕЧАНИЕ №1: основная проблема/проблема в том, что ch и ch2 объявлены как одиночные переменные char. Они могут быть «a» или «b» или «\ n» или 0x20 или любой другой символ. Это НЕ массивы символов или указатели. У вас есть комментарий, где вы читаете один char 'ch = getchar() // получая строку текста', этот комментарий неверен (хотя у вас есть хорошие комментарии, показывающие, что вы думаете в вашем примере), во всяком случае, ch = getchar() 'просто получает один символ. Позже вы рассматриваете ch2 как массив.

char ch,ch2; 
. . . then later: 
if (ch == ch2[&i]) { // ouch, does that even compile? yes. oh dear. how do we explain this one?! 

ouch! Это неправильно, потому что он рассматривает ch2 как массив/указатель. То, как работает ваш цикл, теперь ch2 устанавливается на самый первый символ. И это никогда не меняется.

Он может скомпилировать все в порядке, НО это дает предупреждение? На самом деле, справедливо для вас. Я не получаю предупреждение. gcc 4.8.2 совершенно доволен тем, что ch2 является символом char и делает (ch == ch2 [& i]). Теперь ch2 [& i] может быть синтаксически корректным кодом, он будет компилироваться в порядке. Он даже будет работать нормально. Но что это значит? Это семантически допустимо? Давайте забудем об этой странной вещи до самого конца.

Обратите внимание, что вы можете скомпилировать c, но это может быть довольно много ошибок указателя и может привести к сбою/зависанию. Так . , , быть осторожен :-).

Попробуйте сделать изменения, как это:

ch = getchar(); // does not get the line of text, just gets one char 
. . . 
ch2 = 0; // for the first iteration of loop 
if (ch == ch2) { // change from ch2[&i] - wow :-) very confused! 
. . . 
    ch2 = ch; // set ch2 to the last char read before reading new 
    ch = getchar(); // read one new char 

Это делает работу кода только с помощью 2 символов. ch и ch2. Вы не используете i. Вы не используете указатель массива или строки или указателя.

ПРИМЕЧАНИЕ # 1.1: ch2 [& i] компилируется и запускается. НО ЭТО НЕПРАВИЛЬНО, OHHHH SOOOOOO НЕПРАВИЛЬНО. И странно.Как работает доступ к массиву в c? Синтаксис c [& i] является «правильным» (возможно, зависит от компилятора). НО, пожалуйста, не используйте этот синтаксис! Что это значит? Это семантически сомнительно. Похоже, возможно, намерение состояло в том, чтобы использовать массив символов вместе с i. Быстрый пример, показывающий, назначая и чтение из символьного массива правильно:

char s[100]; // string of 100 chars, accessing index below 0 and above 99 is bad 
i=0; 
s[i]='H'; // assign char 'H' to first letter of string (s[0]) 
i++;   // increment i, i is now 2. 
s[i]='i'; 
i++; 
s[i]=0; // end string 
printf("s[0]=%c s[1]=%c s[2]=%02x string:%s",s[0],s[1],s[2],s); 

Примечание # 1.2: ch2 [& я] компилируется и работает. Как и зачем он компилируется?

& я означает указатель на переменную я в памяти

% р в Printf будет показывать значение указателя

Так попробуйте добавить это пример кода:

printf("%p %p %p\n", &ch, &ch2, &i); 

// ch2[i] will not compile for me, as ch2 is not an array. syntax error 

// ch2[&i] DOES compile for me. But . . what is the value ? 
// What does it mean. I do not know! Uncharted territory. 
printf("ch2[&i]:%p:%02x\n",&i,ch2[&i]); 
printf("ch2[&ch]:%p:%02x\n",&ch,ch2[&ch]); 
printf("ch2[&ch2]:%p:%02x\n",&ch2,ch2[&ch2]); 

Я получая что-то подобное, каждый из них меняет указатели:

ch2[&i]:0xbfa0c54c:bfa0de71 
ch2[&ch]:0xbfa0c54a:08 
ch2[&ch2]:0xbfa0c54b:00 

Открытое объяснение:

Обычно мы объявляем массив, например. 'int array [100];' где 100 - размер массива. array [0] - это первый элемент, а массив [99] - последний. Мы индексируем массив с помощью целого числа. Теперь все массивы являются указателями. SO * массив совпадает с массивом [0]. * (массив + 1) совпадает с массивом [1].

Пока все хорошо.

Теперь * (1 + массив) также совпадает с массивом [1]. Можно сказать, что int i = 7; И используйте массив [i] или * (массив + 7) или * (7 + array) OR i [array], чтобы показать 7-й элемент массива. i [массив] любому программисту должен выглядеть очень ОЧЕНЬ WROOOONG (не синтаксически неправильно, НО философски/семантически/морально неправильно!)

Хорошо. Хорошо. Успокойся. Jeez. Теперь с 'char ch2;' ch2 - это один символ. Это НЕ массив. ch2 [& i] работает (работает как в компиляции, так и иногда/в основном работает нормально !!!), потому что последняя (WROOOONG) i [array] нотация действительна. Глядя на ВИДОВ интересно:

i[array] === <type int>[<type int *>]. 
ch2[&i] === <type char>[<type int *>]. 

C счастливо и весело бросает символ в целое и INT может быть добавлен указатель или использовать в качестве указателя. ИСКЛЮЧИТЕЛЬНО В ЗАКЛЮЧЕНИИ: синтаксис ch2 [& i] оценивает целое число при смещении: & i (указатель на целое число i) значение PLUS символа ch2. Нет никакой веской причины использовать этот синтаксис! Это опасно. Вы получаете доступ к ячейке памяти, которая может быть или не быть действительной, и поскольку ваш указатель указывает на одну переменную, местоположение недействительно в отношении любых других значений.

Смотрите здесь: Why 'c[&i]' compiles while 'c[i]' doesn't?

ПРИМЕЧАНИЕ # 2: смотреть брекет {}. а главное закрытие} и отступ не совпадают в примере. Программа работает нормально с этой ошибкой. Путчар (ch) работает как часть последнего. Команды после этого запуска в конце цикла while.

ПРИМЕЧАНИЕ # 3 main должно возвращать int не пусто main необязательно не принимает ничего '()' или '(int argc, char ** argv)'.

Смежные вопросы