Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Предыдущий символ в строке, Си

51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
У меня проблема. второй день сижу и туплю в моник. у меня не работает эта строка
if ((s1[-1]==' ') || !s1[-1])
она должна проверять предыдущий символ на пробел либо начало строки
47K
08 ноября 2009 года
Cka3o4HuK
31 / / 21.10.2009
s[-1] проверяет не предыдущий элемент, а элемент с индексом -1, который не принадлежит данной строке
я думаю должно быть что-то вроде
 
Код:
if((s1[i-1]==' ') || (i-1==0))
51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
Цитата: Cka3o4HuK
s[-1] проверяет не предидущий элемент, а элемент с индексом -1, который не принадлежит данной строке




У меня s1 - это указатель (char *s1). Тогда s1[-1] означает *(s1-1).

47K
08 ноября 2009 года
Cka3o4HuK
31 / / 21.10.2009
Если s1 указывает на начало строки, то s1[-1] будет все равно вылезать за рамки вашей строки влево.
51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
в том-то и дело. вот это
 
Код:
!s1[-1]

должно проверять, существует ли элемент с номером *(s1-1)
47K
08 ноября 2009 года
Cka3o4HuK
31 / / 21.10.2009
Мне почему то кажется, что эта строка никоим образом не проверяет существование элемента. Могу ошибаться, но в if это выражение будет истинным если s1[-1] == 0(или возможно даже <=0) и ложью при любом положительном значение.
51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
ок, а как же тогда проверить?
274
08 ноября 2009 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: i-dead
в том-то и дело. вот это
 
Код:
!s1[-1]

должно проверять, существует ли элемент с номером *(s1-1)



нет. это не проверяет существование елемента. оно проверяет, не равно-ли нулю значение лежайшее по адрессу (s1-1) а там всегда что-то будет. Буд-то мусор какой-то, или значение из другой переменной..
нужно проверять что-то типа (s1>s). если s - указатель на начало строки

АПД: а также не забыть контролировать вылаз за пределы строки

АПД2: Да, и почему Вас, стоит ИЛИ в условии? Ведь по такому условию получится, что в случае пробельного символа на (s1-1) проверка принадлежности строке - уже не важна, да и она даже не осуществится.

51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
просто мне по условию надо, чтобы предыдущий символ (т.е. s1[-1]) был либо пробел, либо начало строки.
Цитата:

там всегда что-то будет


спс, это я как-то упустил

274
08 ноября 2009 года
Lone Wolf
1.3K / / 26.11.2006
ну тогда
 
Код:
if((s1==s) || s[-1]==' ')

ну или как вы там построете условие для первого символа.
Именно такой порядок нужен, потому что очень важно сперва проверить на первый символ Потому что, если сперва проверить пробел, то мы не можем быть уверены, что мы не на первом символе. А специфика выражений a || b, такова, что если а - истинно выражение b - даже не проверяется.
Т.е. в моем варианте, если мы не на первом символе, то проверяем пробельный, а так как мы не на первом за началостроки мы не вылезем
51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
идея, конечно, хорошая. но все равно это условие циклит все.
полное условие задачи: в тексте нужно все, что может являться именем переменной в Си, привести к верхнему регистру
вот весь код, кому интересно
Код:
#include "stdafx.h"
#include "windows.h"
#include "conio.h"
#define q 100

int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
char **text;
int l,i=0,i1;
text=(char**)malloc(sizeof(char*));
text[0]=(char*)malloc(sizeof(char)*100);
text [0][0]='1';
while (1)                               //ввод текста
{
    char c='\0';
    l=0;
    while ((c!='\n') && (l<100))
 {
    c=getchar();
    text[l++]=c;
   
 }
 text[--l]='\0';
 if (l>0)
 {
    i++;
    text=(char**)realloc(text,(i+1)*sizeof(char*));
    text=(char*)malloc(sizeof(char)*100);
 }
 else break;
}

for (int i1=0; i1<=i; i1++)                                    
{
    char *s1,*s2,*s3;
    s1=text[i1];
    s3=text[i1];
    while (*s1)
    {   while (*s1)
        {
            if ((s1[0]>='a' || s1[0]<='z') && (s1==s3 || s1[-1]==' '))
                break;
            else s1++;
        }
        s2=s1;
        if (s1==s3 || s1[-1]==' ')
        {
        while ((s2[0]>='a') && (s2[0]<='z') || s2[1]==' ' || s2[1]==0) s2++;
        if (s2[1]==' ' || s2[1]=='\0')
        while (s1!=s2)
        {
            *s1=*s1-('a'-'A');
            s1++;
        }   }
    }

    text=s1;
}



//printf ("конец");
for (int i1=0;i1<=i;i1++)
    printf("\n%s", text[i1]);
return (0);
}
20K
08 ноября 2009 года
sem2711
124 / / 23.09.2009
Цитата: i-dead
что может являться именем переменной в Си


Интересно, а что по Вашему является критерием отбора?

Цитата:
 
Код:
if ((s1[0]>='a' || s1[0]<='z') && (s1==s3 || s1[-1]==' '))

 
Код:
while ((s2[0]>='a') && (s2[0]<='z') || s2[1]==' ' || s2[1]==0) s2++;


Неужели все слова набранные латиницей?

51K
08 ноября 2009 года
i-dead
14 / / 08.11.2009
нет, не только, конечно! но она даже так не работает
274
08 ноября 2009 года
Lone Wolf
1.3K / / 26.11.2006
ух.. не разбирал я код.. какой-то он сильно мудренный. Для данной задачи достаточно простого конечного автомата.
советую почитать про автоматы. Просто не прийдется заморачиватся с такими муторными условиями.
Если знаете, что это такое или же после ознакомления - читаем дальше этот пост.
Я бы выделил 3 состояния:
- Ожидается начало переменной - просто перебираем все символы пока не встретим тот которы может пренадлежат переменной(суддя по всему тут возможны только пробелы или знаки препинания)
- Начало переменной не возможно - перебираем символы пока не встретим такого, что нас выбросит в первое состояние(т.е. опять же пробелы...etc.)
- Формуруем переименную - запоминаем все символы по строке, пока не встрети такого что означает что переменная закончена(пробел, знаки препинания) или такой что скажет, что это бла непеременная(какой-то спец символ, что не допускается в именнах переменных)

Собственно тогда мы получим один больщой цикл, в котором в зависимости от текущего состояния автомат и пришедшого символа будет осуществлятся то или инное действие. Я бы посоветовал организовать все на процедурах и функциях..
297
09 ноября 2009 года
koodeer
1.2K / / 02.05.2009
В код особо не вникал, но вот эта строка:
 
Код:
if ((s1[0]>='a' || s1[0]<='z') && (s1==s3 || s1[-1]==' '))
бросилась в глаза. Условию (s1[0]>='a' || s1[0]<='z') соответствует любой символ. Очевидно, нужно (s1[0]>='a' && s1[0]<='z')
51K
11 ноября 2009 года
i-dead
14 / / 08.11.2009
вот, переделал прогу. все работает, но после вывода выдает ошибку
Код:
#include "stdafx.h"
#include "windows.h"
#include "conio.h"
#define q 100

int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
char **text;
int l,i=0,i1;
text=(char**)malloc(sizeof(char*));
text[0]=(char*)malloc(sizeof(char)*100);
text [0][0]='1';
while (1)
{
    char c='\0';
    l=0;
    while ((c!='\n') && (l<100))
 {
    c=getchar();
    text[l++]=c;
   
 }
 text[--l]='\0';
 if (l>0)
 {
    i++;
    text=(char**)realloc(text,(i+1)*sizeof(char*));
    text=(char*)malloc(sizeof(char)*100);
 }
 else break;
}
i1=i;
for (i=0; i<=i1; i++)
{
int j=0;
while(text[j])
{
while(text[j]==' ') j++;
if(!(text[j]<='z' && text[j]>='a') && !(text[j]<='Z' && text[j]>='A'))
while(text[j]!=' ' && text[j]) j++;

while(text[j]!=' ' && text[j])
{
if (text[j]!='_')
if (text[j]<='z' && text[j]>='a')
text[j]-='a'-'A';
j++;
}
}
}



for (int i1=0;i1<=i;i1++)
    printf("\n%s", text[i1]);
return (0);
}
20K
11 ноября 2009 года
sem2711
124 / / 23.09.2009
У меня все работает без ошибок (правда я подключал другие заголовки и убрал функции установки кодировки консоли). Другое дело, что в результате я получил не совсем то, что ожидал автор задачи. Программа просто перевела все введенные буквы в верхний регистр. Может, Вы объясните словами, что же Вы ожидаете на выходе? А что ожидается на входе? Того же результата (что получился у Вас) можно добиться несколькими строками, а у Вас там куча каких-то вложенных циклов, условий. Код реально очень запутанный и некомментированный. Да, ну и память надо в кучу вернуть перед выходом.
51K
12 ноября 2009 года
i-dead
14 / / 08.11.2009
все, сделал, сдал. а насчет ожидания вывода: прога должна приводить в верхний регистр слово, начинающееся с буквы.
20K
13 ноября 2009 года
sem2711
124 / / 23.09.2009
Цитата:
прога должна приводить в верхний регистр слово, начинающееся с буквы.


Вот программа, которая делает то же самое, но немного текст покороче:

Код:
#include <stdio.h>
#include <string.h>
#include <ctype.h>

main()
{
    printf("Enter some words:\n");
    char string[1000] = "";
    gets(string);
    printf("You entered:\n%s\n", string);
    int i;
    for (i = 0; i < strlen(string); ++i)
    {
        string = toupper(string);
    }
    printf("Now we've got:\n%s\n", string);
    printf("Done\n");
}
274
13 ноября 2009 года
Lone Wolf
1.3K / / 26.11.2006
ну-ну... _5not_word - тоже переведет - а не должна...
12K
13 ноября 2009 года
Ghox
297 / / 26.07.2009
Если переделать пример sem2711 с учетом правильного замечания Lone Wolf:
Цитата: Lone Wolf
ну-ну... _5not_word - тоже переведет - а не должна...


т.к. автору требовалось

Цитата: i-dead
все, сделал, сдал. а насчет ожидания вывода: прога должна приводить в верхний регистр слово, начинающееся с буквы.


то можно сделать так - с использованием булевских переменных для определения того, нужно ли переводить текущий символ в верхний регистр или нет:

Код:
#include <stdio.h>
#include <string.h>
#include <ctype.h>

main()
{
    printf("Enter some words:\n");
    char string[1000] = "";
    gets(string);
    printf("You entered:\n%s\n", string);
    int i;
    bool begin_ = true; // является ли началом слова
    bool toupper_; // нужно ли применить toupper к текущему символу
    for (i = 0; i < strlen(string); ++i)
    {
        if(begin_)
            toupper_ = (string >= 'A' && string <= 'Z')
                || (string >= 'a' && string <= 'z');
        begin_ = (string == ' ');
        if(!begin_ && toupper_)
            string = toupper(string);
    }
    printf("Now we've got:\n%s\n", string);
    printf("Done\n");
}

P.S. Если используемый компилятор C булевские переменные не поддерживает (изначально их в C не было), то вместо них можно использовать переменные int (значение 1 вместо true и 0 вместо false);
274
13 ноября 2009 года
Lone Wolf
1.3K / / 26.11.2006
мм.. тоже некатит, хотя может я неправильно понял условие, но как по мне требовалось, чтобы такая строка
 
Код:
4fss^ sjdss fsdd7$$d

стала такой
 
Код:
4fss^ SJDSS fsdd7$$d

В случае Ghox она станет
 
Код:
4fss^ SJDSS FSDD7$$D
20K
13 ноября 2009 года
sem2711
124 / / 23.09.2009
Похоже, немного опоздал, но время потратил - посему вот:
Код:
#include <stdio.h>
#include <string.h>
#include <ctype.h>

/* ff() "перематывает" строку str до очередного пробела
и возвращает его индекс в str. index - первый символ после пробела */
int ff(char *str, int index);

/* up() приводит все символы до очередного пробела
к верхнему регистру. Возвращает индекс очередного
пробела в str. index - первый символ после пробела */
int up(char *str, int index);

main()
{
    printf("Enter some words:\n");
    char string[1000] = "";
    gets(string);
    printf("You entered:\n%s\n", string);
    /* обработка начала строки */
    int i = 0;
    if (isalpha(string))
        i = up(string, i);
    else
        i = ff(string, i);
   
    while (i < strlen(string))
    {
        if (isalpha(string[i + 1]))
            i = up(string, i + 1);
        else
            i = ff(string, i + 1);
    }
    printf("Now we've got:\n%s\n", string);
    printf("Done\n");
}

int ff(char *str, int index)
{
    while (!isspace(str[index]))
    {
        ++index;
        continue;
    }
    return index;
}
int up(char *str, int index)
{
    while (!isspace(str[index]))
    {
        str[index] = toupper(str[index]);
        ++index;
    }
    return index;
}

Цитата:
мм.. тоже некатит


А вот по мнению топикстартера очень даже катит. Нет смысла еще раз цитировать его.

51K
13 ноября 2009 года
i-dead
14 / / 08.11.2009
sem2711, это несколько не то. Lone Wolf, да, она переводит все в верхний регистр.
P.S. нам нельзя использовать такие стандартные функции, как strlen и toupper
3
13 ноября 2009 года
Green
4.8K / / 20.01.2000
Цитата: i-dead

P.S. нам нельзя использовать такие стандартные функции, как strlen и toupper


Ну так напиши свои, делов то.

274
13 ноября 2009 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: Green
Ну так напиши свои, делов то.



Так, как я понял автор вопрос уже решил, и тут пошло обсуждение как можно было бы сделать лучше )

51K
22 ноября 2009 года
i-dead
14 / / 08.11.2009
ага, так оно и есть :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог