Предыдущий символ в строке, Си
if ((s1[-1]==' ') || !s1[-1])
она должна проверять предыдущий символ на пробел либо начало строки
я думаю должно быть что-то вроде
У меня s1 - это указатель (char *s1). Тогда s1[-1] означает *(s1-1).
должно проверять, существует ли элемент с номером *(s1-1)
должно проверять, существует ли элемент с номером *(s1-1)
нет. это не проверяет существование елемента. оно проверяет, не равно-ли нулю значение лежайшее по адрессу (s1-1) а там всегда что-то будет. Буд-то мусор какой-то, или значение из другой переменной..
нужно проверять что-то типа (s1>s). если s - указатель на начало строки
АПД: а также не забыть контролировать вылаз за пределы строки
АПД2: Да, и почему Вас, стоит ИЛИ в условии? Ведь по такому условию получится, что в случае пробельного символа на (s1-1) проверка принадлежности строке - уже не важна, да и она даже не осуществится.
там всегда что-то будет
спс, это я как-то упустил
ну или как вы там построете условие для первого символа.
Именно такой порядок нужен, потому что очень важно сперва проверить на первый символ Потому что, если сперва проверить пробел, то мы не можем быть уверены, что мы не на первом символе. А специфика выражений a || b, такова, что если а - истинно выражение b - даже не проверяется.
Т.е. в моем варианте, если мы не на первом символе, то проверяем пробельный, а так как мы не на первом за началостроки мы не вылезем
полное условие задачи: в тексте нужно все, что может являться именем переменной в Си, привести к верхнему регистру
вот весь код, кому интересно
#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);
}
Интересно, а что по Вашему является критерием отбора?
Неужели все слова набранные латиницей?
советую почитать про автоматы. Просто не прийдется заморачиватся с такими муторными условиями.
Если знаете, что это такое или же после ознакомления - читаем дальше этот пост.
Я бы выделил 3 состояния:
- Ожидается начало переменной - просто перебираем все символы пока не встретим тот которы может пренадлежат переменной(суддя по всему тут возможны только пробелы или знаки препинания)
- Начало переменной не возможно - перебираем символы пока не встретим такого, что нас выбросит в первое состояние(т.е. опять же пробелы...etc.)
- Формуруем переименную - запоминаем все символы по строке, пока не встрети такого что означает что переменная закончена(пробел, знаки препинания) или такой что скажет, что это бла непеременная(какой-то спец символ, что не допускается в именнах переменных)
Собственно тогда мы получим один больщой цикл, в котором в зависимости от текущего состояния автомат и пришедшого символа будет осуществлятся то или инное действие. Я бы посоветовал организовать все на процедурах и функциях..
#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);
}
Вот программа, которая делает то же самое, но немного текст покороче:
#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");
}
т.к. автору требовалось
то можно сделать так - с использованием булевских переменных для определения того, нужно ли переводить текущий символ в верхний регистр или нет:
#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);
стала такой
В случае Ghox она станет
#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;
}
А вот по мнению топикстартера очень даже катит. Нет смысла еще раз цитировать его.
P.S. нам нельзя использовать такие стандартные функции, как strlen и toupper
P.S. нам нельзя использовать такие стандартные функции, как strlen и toupper
Ну так напиши свои, делов то.
Так, как я понял автор вопрос уже решил, и тут пошло обсуждение как можно было бы сделать лучше )