Парни помогите с С

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by eregis, 8 Sep 2010.

Thread Status:
Not open for further replies.
  1. eregis

    eregis Member

    Joined:
    15 Jul 2010
    Messages:
    104
    Likes Received:
    5
    Reputations:
    -5
    Парни помогите завтра семинар, надо прогу которая считает сколько символов в предложении, на С++ !!!
    Плис думаю поймете тупого студента ))))))))
     
  2. kosmo987

    kosmo987 Member

    Joined:
    28 Apr 2010
    Messages:
    0
    Likes Received:
    6
    Reputations:
    1
    думаю на плюсы не будет проблем переделать..



    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication1
    {
    class Program
    {
    static void Main(string[] args)
    {

    string str;
    Console.WriteLine("Введите предложение");
    str = Console.ReadLine();
    Console.WriteLine("В предложении "+str.Length+" символов");
    Console.ReadLine();
    }
    }
    }
     
  3. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    здесь даже больше, чем тебе нужно))
    https://forum.antichat.ru/showpost.php?p=2009151&postcount=2556
     
  4. good_man

    good_man New Member

    Joined:
    24 May 2010
    Messages:
    112
    Likes Received:
    3
    Reputations:
    -2
    для формы:

    кидаешь на форму два мемо, баттон. в обрабочик он клик или OnChange у мемо кидаешь код:

    AnsiString str=(Memo1->Text);
    String info="Кол-во символов в предложении: ";
    int probel=0;
    while (str.Pos(" "))
    {
    str.Insert("_",str.Pos(" "));//заменим пробелы для цикла чтоб их можно было посчитать
    str.Delete(str.Pos(" "),1);
    probel++; //считаем сколько пробелов
    }



    Memo2->Text=info+(str.Length()-probel); //выводим кол-во символов и вычитаем кол-во пробелов :)
     
  5. cheater_man

    cheater_man Member

    Joined:
    13 Nov 2009
    Messages:
    651
    Likes Received:
    44
    Reputations:
    7
    Code:
    #include <iostream>
    #include <string>
    #include <io.h>
    #include <conio.h>
    
    
    int main()
    {
      char str [80];
      int i,z=0;
    
      printf ("Enter your string ");
      scanf ("%s",str);
      for(i=0;i<80;i++)
      {
    	  if(str[i]>=32&&str[i]<=254)
    			z++;
      }
      printf("Symbols is %d",z);
      getch();
      return 0;
    }
    
    :D
    http://ascii.org.ru/ascii.pdf
     
    #5 cheater_man, 8 Sep 2010
    Last edited: 8 Sep 2010
  6. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    cheater_man, плохо:
    PHP:
    //нафига столько всего? Тем более string
    #include <iostream>
    #include <string>
    #include <io.h>
    #include <conio.h>


    int main()
    {
      
    char str [80];
      
    int i,z=0//size_t делаем

      
    printf ("Enter your string ");
      
    scanf ("%s",str); //ограничение по длине сделать
      //иначе переполнение возможно
      //а еще - первый попавшийся пробел и scanf вылетит
      //дальше, не дочитав предложение до конца

      
    for(i=0;i<80;i++) //цикл по всем 80?..
      
    {
          if(
    str[i]>=32&&str[i]<=254//а букву "я" забыли?
                
    z++;
      }
      
    printf("Symbols is %d",z); //%u по-хорошему
      
    getch();
      return 
    0;
    }
    Хорошо:
    PHP:
    #include "stdio.h"

    int main()
    {
      
    char str [256];
      
    size_t icnt 0len;

      
    printf("Enter sentence> ");
      
    scanf("%255[^\n]"str); //хавает всё предложение до конца

      
    len strlen(str); //цикл до длины строки

      
    for(0leni++)
      {
          if((
    unsigned char)str[i] > 32//будем считать все символы, кроме тех,
              //чьи ascii меньше 33 (пробел тоже не считаем)
              //сравнение беззнаковое делаем
              
    cnt++;
      }

      
    printf("Symbols count: %u"cnt);
      
      
    getch();
      return 
    0;
    }

    А вообще если чисто число символов с учетом пробелов - то это ж просто strlen.
     
    #6 GRRRL Power, 9 Sep 2010
    Last edited: 9 Sep 2010
  7. Bers

    Bers Member

    Joined:
    17 May 2010
    Messages:
    78
    Likes Received:
    30
    Reputations:
    26
    Место тупого студента - на улице с метлой в руках. Такую вещь не суметь написать... 1-й курс, я полагаю? :)
    По теме:
    PHP:
    int length(charbuff)
    {
      
    int len 0;
      while( 
    buff[len++] != NULL)
      {  }

      return 
    len;  
    }
    то же самое с использованием библиотечной функции:

    PHP:
    int length(charbuff)
    {
      return 
    strlen(buff);
    }
    Это если ты имеешь в виду - сколько символов в предложении. Если речь о буквах - то ответ приводился выше.
    Позорище, вообще говоря.


    UPD:

    Замечательный пример того, как не надо писать код.
    Превратить простейшую задачку в такое чудо... Господи... Нет слов. good_man, прикинь-ка для начала наихудшую и наилучшую сложность своего алгоритма. Намекну: что будет присходить, если вся строка - одни пробелы? Сколько будет проходов по строке для поиска пробела? И зачем считать число пробелов, если ТС просил посчитать число символов?
     
    #7 Bers, 9 Sep 2010
    Last edited: 9 Sep 2010
  8. good_man

    good_man New Member

    Joined:
    24 May 2010
    Messages:
    112
    Likes Received:
    3
    Reputations:
    -2
    >>Намекну: что будет присходить, если вся строка - одни пробелы? Сколько будет проходов по строке для поиска пробела?

    отвечаю: цикл пройдет ровно столько раз сколько есть в строке пробелов. а знаете почему? потому что все они заменятся на "_" и цикл прекратится после последней замены.

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

    >>И зачем считать число пробелов, если ТС просил посчитать число символов?

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

    и я непрогер. просто любитель.
     
    #8 good_man, 9 Sep 2010
    Last edited: 9 Sep 2010
  9. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Тут рядом КО подсказывает что таки пробел это частный случай символа
     
  10. good_man

    good_man New Member

    Joined:
    24 May 2010
    Messages:
    112
    Likes Received:
    3
    Reputations:
    -2
    да я неспорю млин что пробел это символ.

    по вашему я значит должен был тупо запостить:

    AnsiString str=(Memo1->Text);
    Memo2->Text=str.Length();

    так чтоль получается?

    и я думаю что все же пробелы учитывать ненужно, т.к. в первом посте речь идет о предложении.
     
    #10 good_man, 9 Sep 2010
    Last edited: 9 Sep 2010
  11. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    2GRRRL Power
    for(i = 0; i < len; i++)
    {
    if((unsigned char)str > 32) //будем считать все символы, кроме тех,
    //чьи ascii меньше 33 (пробел тоже не считаем)
    //сравнение беззнаковое делаем
    cnt++;
    }

    сравнение знаковое
    (signed int)unsigned char > 32
    тоесть unsigned char перед сравненем
    приводится к signed int
    тоже самое ((unsigned char*)str) > 32
    в обоих случаях имеем в результате signed int
    просто по пути избавляемся от эффекта распространения знака
    еще можно так (str & 0xff) > 32
     
  12. Bers

    Bers Member

    Joined:
    17 May 2010
    Messages:
    78
    Likes Received:
    30
    Reputations:
    26
    Мой намек остался непонятым.

    Нет, не на это.

    1. Я не говорил, что он зависнет, я вообще не на это намекал.
    2. Я предпочитаю думать головой, а не компилятором, и до написания кода, а не после.

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


    Поскольку мой вопрос остался без ответа, поясню.
    1. Пусть вся строка - не пробелы. Тогда потребуется один проход по строке (функцией str.Pos(" ")). Наилучший случай.
    2. Пусть вся строка - пробелы. Тогда потребуется: N неполных проходов (до первого пробела, которые будут заменяться по одному начиная с первого) по строке N раз, что даст в сумме 2 полных прохода (можешь посчитать на досуге), плюс еще один проход по всей строке до конца (чтобы определить, что цикл завершился). Наихудший случай.
    Теперь ясно, на что я намекал?
    Дальше. Вот это:
    PHP:
    str.Insert("_",str.Pos(" "));
    str.Delete(str.Pos(" "),1);
    Класс AnsiString - суть обертка над массивом (поправьте меня, если я не прав, но насколько я в курсе, это так). Надо объяснять, сколько стоит вставка и удаление элемента в массиве? В двух словах - недешево. Если уж на то пошло, было бы куда быстрее просто заменять элемент в строке.

    Ну и сама идея корежить строку для простейшего дела - ущербна по определению. Всего-то надо было написать:
    PHP:
    int count_of_spaces(const charbuffer)
    {
      
    int count 0;
      
    int pos 0;
      while(
    buff[pos] != NULL)
      {
        if(
    buff[pos] == ' ')
         ++
    count;
     
        ++
    pos;
      }

      return 
    pos;
    }
    Строго один проход по строке. код в полторы строчки. Алгоритм очевиден. Проще некуда.

    А зачем тогда отвечать на вопрос ТС? Чтобы его ввести в заблуждение? :)

    Вообще было бы полезнее.
     
  13. altblitz

    altblitz Elder - Старейшина

    Joined:
    5 Jun 2009
    Messages:
    3,691
    Likes Received:
    3,146
    Reputations:
    236
    RegEx, регулярные выражения - сортируют текстовые массивы на C, с выводом числа символов, с поиском в тексте и многом другом .

    краткая справка - в help TotalCommander.

    в институте - преподы могут и не понять подобное,
    и обвинить в богохульстве и всяких прочих грехах.

    полная справка - man regex
     
  14. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84

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

    Вот код MS visual studio при сравнении с (unsigned char):
    PHP:
    008B101F  |.  8A5C24 10     MOV BL,BYTE PTR SS:[ARG.2//аргумент взял из стека
    008B1023  |.  80FB 20       CMP BL,20
    008B1026  
    |.  76 13         JBE SHORT 008B103B
    Вот ее же код, но при сравнении просто char без преобразования в unsigned (лишние инструкции убрал):
    PHP:
    008B1038  |.  80FB 20       CMP BL,20
    008B103C  
    |.  7E 10         JLE SHORT 008B104E
    Как видно, и там и там сравниваются байты, а не DWORD'ы, и в первом случае сравнение именно беззнаковое, а во втором - знаковое.



    Первый ответ вообще C#, а второй - C++.
     
    #14 GRRRL Power, 9 Sep 2010
    Last edited: 9 Sep 2010
    1 person likes this.
  15. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    2GRRRL Power
    можно пример вашего кода у себя проверю ?
    вот мой код и во что он превращается

    1)
    if((unsigned char)str > 32)
    0041127A 8B 45 F8 mov eax,dword ptr
    // беззнаковое расширение
    0041127D 0F B6 4C 05 FC movzx ecx,byte ptr str[eax]
    00411282 83 F9 20 cmp ecx,20h
    // знаковое сравнение
    00411285 7E 10 jle main+37h (411297h)
    2)
    if(((unsigned char*)str) > 32)
    0041127A 8B 45 F8 mov eax,dword ptr
    // беззнаковое расширение
    0041127D 0F B6 4C 05 FC movzx ecx,byte ptr str[eax]
    00411282 83 F9 20 cmp ecx,20h
    // знаковое сравнение
    00411285 7E 10 jle main+37h (411297h)
    3)
    if((str & 0xff) > 32)
    0041127A 8B 45 F8 mov eax,dword ptr
    // знаковое расширение
    0041127D 0F BE 4C 05 FC movsx ecx,byte ptr str[eax]
    00411282 81 E1 FF 00 00 00 and ecx,0FFh
    00411288 83 F9 20 cmp ecx,20h
    // знаковое сравнение
    0041128B 7E 10 jle main+3Dh (41129Dh)

    теперь беззнаковое сравнение

    1)
    if((unsigned char)str > 32U)
    0041127A 8B 45 F8 mov eax,dword ptr
    // беззнаковое расширение
    0041127D 0F B6 4C 05 FC movzx ecx,byte ptr str[eax]
    00411282 83 F9 20 cmp ecx,20h
    // беззнаковое сравнение
    00411285 7E 10 jbe main+37h (411297h)
    2)
    if(((unsigned char*)str) > 32U)
    0041127A 8B 45 F8 mov eax,dword ptr
    // беззнаковое расширение
    0041127D 0F B6 4C 05 FC movzx ecx,byte ptr str[eax]
    00411282 83 F9 20 cmp ecx,20h
    // беззнаковое сравнение
    00411285 7E 10 jbe main+37h (411297h)
    3)
    if((str & 0xff) > 32U)
    0041127A 8B 45 F8 mov eax,dword ptr
    // знаковое расширение
    0041127D 0F BE 4C 05 FC movsx ecx,byte ptr str[eax]
    00411282 81 E1 FF 00 00 00 and ecx,0FFh
    00411288 83 F9 20 cmp ecx,20h
    // беззнаковое сравнение
    0041128B 7E 10 jbe main+3Dh (41129Dh)
     
  16. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    PHP:
    #include "windows.h"

    int _stdcall WinMain(int qint qqint qqqint qqqq)
    {
        
    char a q;
        
    char b qq;

        if((
    unsigned char)32)
            
    MessageBoxA(0,"(unsigned char)a more than 32\r\n","",0);

        if((
    unsigned char)32)
            
    MessageBoxA(0,"(unsigned char)b more than 32","",0);

        if(
    32)
            
    MessageBoxA(0,"(signed char)b more than 32","",0);

        
    ExitProcess(0);
    }
    Код бред, просто беру аргументы из стека, чтобы компилятор сразу не раскрывал сравнение. Студия 2008, включена оптимизация по скорости (/O2)
     
  17. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    2GRRRL Power
    оптимизация влияет но только стоит усложнить задачу чтоб он не знал что сравнение с 32 идет как он начинает делать знаковое сравнение без отсебятины тоесть в любом случае следует ожидать знаковое сравнение а то что он может соптимизировать это только зная значение второго операнда тогда да беззнаковое но это исключение из правил а не наоборот
    int _stdcall WinMain(int q, int qq, int qqq, int qqqq)
    {
    00401000 51 push ecx
    char a = q;
    char b = qq;
    volatile int _32 = 32;

    if((unsigned char)a > _32)
    00401001 0F B6 4C 24 08 movzx ecx,byte ptr [esp+8]
    00401006 C7 04 24 20 00 00 00 mov dword ptr [esp],20h
    0040100D 8B 04 24 mov eax,dword ptr [esp]
    00401010 3B C8 cmp ecx,eax
    00401012 56 push esi
    00401013 8B 35 B0 20 40 00 mov esi,dword ptr [__imp__MessageBoxA@16 (4020B0h)]
    00401019 7E 10 jle WinMain+2Bh (40102Bh)
    MessageBoxA(0,"(unsigned char)a more than 32\r\n","",0);
    0040101B 6A 00 push 0
    0040101D 68 04 21 40 00 push offset string "" (402104h)
    00401022 68 08 21 40 00 push offset string "(unsigned char)a more than 32\r\n" (402108h)
    00401027 6A 00 push 0
    00401029 FF D6 call esi

    if((unsigned char)b > _32)
    0040102B 8B 54 24 04 mov edx,dword ptr [esp+4]
    0040102F 53 push ebx
    00401030 8A 5C 24 14 mov bl,byte ptr [esp+14h]
    00401034 0F B6 C3 movzx eax,bl
    00401037 3B C2 cmp eax,edx
    00401039 7E 10 jle WinMain+4Bh (40104Bh)
    MessageBoxA(0,"(unsigned char)b more than 32","",0);
    0040103B 6A 00 push 0
    0040103D 68 04 21 40 00 push offset string "" (402104h)
    00401042 68 28 21 40 00 push offset string "(unsigned char)b more than 32" (402128h)
    00401047 6A 00 push 0
    00401049 FF D6 call esi

    if(b > _32)
    0040104B 8B 4C 24 08 mov ecx,dword ptr [esp+8]
    0040104F 0F BE D3 movsx edx,bl
    00401052 3B D1 cmp edx,ecx
    00401054 5B pop ebx
    00401055 7E 10 jle WinMain+67h (401067h)
    MessageBoxA(0,"(signed char)b more than 32","",0);
    00401057 6A 00 push 0
    00401059 68 04 21 40 00 push offset string "" (402104h)
    0040105E 68 48 21 40 00 push offset string "(signed char)b more than 32" (402148h)
    00401063 6A 00 push 0
    00401065 FF D6 call esi

    ExitProcess(0);
    00401067 6A 00 push 0
    00401069 FF 15 00 20 40 00 call dword ptr [__imp__ExitProcess@4 (402000h)]
     
    #17 greki_hoy, 9 Sep 2010
    Last edited: 9 Sep 2010
  18. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    32 объявлено как int, поэтому будет расширение числа до int, 4 байта. В твоем примере кстати первые два случая по-прежнему беззнаковое сравнение (movzx + jle).
     
    #18 GRRRL Power, 9 Sep 2010
    Last edited: 9 Sep 2010
  19. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    а в вашем 32 не как int объявлено ?
    что у вас что у меня int просто в вашем случае он знает значение второго операнда и лепит отсебятину а в моем делает как и должен
    и то у вас такое получается только при оптимизации отключите и смотрите что получится
    да или просто volatile уберите тоже останется объявлено как int но код сгенерит соптимизированный
     
    #19 greki_hoy, 9 Sep 2010
    Last edited: 9 Sep 2010
  20. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Сори, описка, сравнение знаковое. Просто расширение до DWORD беззнаковое.

    Есть подозрение, что 32 может считаться компилятором как байт, потому что помещается в байт. Не спорю, что сравнение может быть знаковым, примеров вы достаточно привели, но расширение до 4 байт будет уже зависеть от наличия (unsigned).
     
Thread Status:
Not open for further replies.