I want to read and print the uppercase version of wide characters in c.
Here's my code:
#include <stdio.h>
#include <wctype.h>
#include <wchar.h>
#include <locale.h>
int main(){
wchar_t sentence[100];
setlocale(LC_ALL, "");
void Edit(wchar_t str[]);
printf("Enter sentence -> ");
wscanf(L"%[^\n]ls", sentence);
Edit(sentence);
getchar();
return 0;
}
void Edit(wchar_t str[]){
int i = -1;
while(str[++i])
if(iswalpha(str[i])) //get rid of whitespaces and other characters
putwchar(towupper(str[i]));
}
It seems that the problem resides in wscanf in fact if I initialize the string like this:
wchar_t sentence[] = L"è";
And the Edit it without reading or asking for a string, it works.
I am using Windows 10, and USA international Keyboard Input,so to make 'è', I have to press ` + e. But I also tried to copy and paste it with ctrl+v, but doesn't work. I am using MINGW with GCC compiler version 6.3.0. I also tried this with my MacBook and doesn't work.
The problem is that if I input "kèy", I want "KÈY" as output. Instead, I get "KSY". I don't know why 'è' outputs 'S' but I tried with other vocals and I get same random characters. However, if I initialize the string as "kèy", I get "KÈY".
Update
I edited wscanf as:
wscanf(L"%ls", sentence);
And it works on my MacBook, but not on windows! Also in this way I can't input spaces, because wscanf stops at the first space.
Update 2
I found something really interesting:
Using this snippet:
int main(){
setlocale(LC_ALL, "");
wchar_t frase[100];
fwide(stdin, 1);
wscanf(L"%ls", frase);
wprintf(L"%ls", frase);
return 0;
}
I found this table and when I input 'è' I get S, which is what the Win column describes. So I tried to input Þ and I got 'è'! I think the problem is with the codes of the cmd, I am using page code: 850
I found a solution
I used system("chcp 1252") to change character set and it WORKED!
Don't use wscanf use fgetws - this will allow you to read white space and protect against buffer overflow. In general its best practice (especially when using user supplied input) to protect against buffer overflow. I edited your code below.
int main(){
wchar_t sentence[100];
setlocale(LC_ALL, "");
void Edit(wchar_t str[]);
printf("Enter sentence -> ");
fgetws(sentence,100,stdin);
Edit(sentence);
getchar();
return 0;
}
void Edit(wchar_t str[]){
int i = -1;
while(str[++i])
if(iswalpha(str[i])) //get rid of whitespaces and other characters
putwchar(towupper(str[i]));
}
You may also want to define your buffer size, and properly allocate and free memory as well.
Related
I am trying to code a C program to start specific functions on the OS X El Capitan.
The code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char mainchoice;
printf(">>> ");
scanf("%s", &mainchoice);
if (strcmp(&mainchoice, "start ftp") == 0) {
system("ftp");
}
else if (strcmp(&mainchoice, "start say") == 0) {
system("say hello");
}
else {
system("say Error")
}
}
This is just a sample code.
When I run it, it always says error via the say command. What am I doing wrong?
Focus here:-
char mainchoice; //declared as a char
scanf("%s", &mainchoice); //using the %s placeholder which is for string
//for character it is %c
Getting the logic behind your code is you want to enter a String not a character.
Make an array of characters like this:-
char mainchoice[20]; //this can hold your string, one character at one index each of the array
Since, your are using multi word in string comparison("start say")
(strcmp(&mainchoice, "start say") == 0)
scanf does not work for multi words. scanf stops reading from the keyboard as soon as you provide a whitespace, tabs, newline.
For solving that problem, use fgets. It's the best way to read multi words or even whole sentences. Never use gets()! It is vulnerable to buffer overflow!
fgets(mainchoice, 20, stdin);
you are declaring mainchoice as a character rather then a string.
use char mainchoice[10]; to create a string.
and replace scanf("%s",&mainchoice) with fgets(mainchoice, 10, stdin);
size is 10 because you are comparing it with a string of length 9, so(9+1 null=10) 10 are enough.
#include<stdio.h>
#include<ctype.h>
#include<stdbool.h>
#include<string.h>
#define number_of_letters 26
bool IsPangram(char* string);
int main(){
char check[100];
when i put the output as "the quick brown fox jumps over the lazy dog" the output is no a pangram
and when i put a to z values on one single line is gives the correct output
scanf("%s",&check);
if(IsPangram(check)){
printf("the string entered is pangram");
}
else{
printf("not a pangram");
}
return 0;
}
there is the function for pangram
bool IsPangram(char* string){
bool flags[number_of_letters];
int size=strlen(string);
bool ispangram=true;
int i;
char c;
// for all the alfabets to be setting them to false
for(i=0;i<number_of_letters;i++){
flags[i]=false;
}
// for converting the uppper case letter to the small one
for(i=0;i<size;i++){
c=tolower(string[i]);
if(islower(c)){
flags[string[i]-'a']=true;
}
}
// for checking the the lettters to no pangram
for(i=0;(i<number_of_letters && ispangram==true);i++){
if(flags[i]==false){
ispangram=false;
}
}
return ispangram;
}
You don't need use & when passing a string as a char *, since arrays decay to pointers when passed as parameters.
So:
scanf("%s",&check);
should be:
scanf("%s", check);
And some general advice: turn on compiler warnings to help catch simple mistakes such as this, and learn basic debugging techniques (stepping through code in your debugger, adding strategic printf statements, etc).
scanf() with the %s format specifier will stop at whitespace. Try fgets(check,100,stdin) instead... that will read (up to) a full line, and limit the number of characters to 99 + nul so you won't exceed the size of check. It may leave a newline as the last character, but your algorithm would ignore that anyway.
Additionally, in IsPangram(), c should be an int instead of a char (to match tolower() etc.), and change this:
// for converting the uppper case letter to the small one
for(i=0;i<size;i++){
c=tolower(string[i]);
if(islower(c)){
flags[string[i]-'a']=true;
}
}
...to this:
// for converting the uppper case letter to the small one
for(i=0;i<size;i++){
c=tolower(string[i]); /* <== c will always be lowercase */
if(isalpha(c)){ /* <== Check that c is a letter */
flags[c-'a']=true; /* <== use c, as string[i] may be uppercase */
}
}
...for the reasons indicated in the added comments.
scanf cannot get strings with spaces. So use fgets
fgets(check,sizeof(check),stdin);
Or use
scanf("%[^\n]s",check);
This reads a string till a newline character is encountered.
The default scanf stops reading when a space is encountered.
Here you go:
#include <ctype.h>
void uc(char*s){for(;*s;*s=toupper(*s),s++);}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char*argv[])
{int i,j,n=0,c[256]={0};
char*s,*w[1024]={NULL};
do w[n]=malloc(1024),fgets(w[n],1024,stdin),w[n][strlen(w[n])-1]='\0',uc(w[n]),n++;
while(n<1024&&strlen(w[n-1]));
for(--n,i=0;i<n;++i)
for(j=0;j<strlen(w[i]);++j)
c[w[i][j]]=1;
for(j=0,i='A';i<='Z';++i)j+=c[i];
printf("It's %sa pangram\n",j==26?"":"not ");
for(i=0;i<=n;free(w[i++]));}
I want to store a string with characters from extend ascii table, and print them.
I tried:
wchar_t wp[] = L"Росси́йская Акаде́мия Нау́к ";
printf("%S", wp);
I can compile but when I run it, nothing is actually displayed in my terminal.
Could you help me please?
Edit: In response to this comment:
wprintf(L"%s", wp);
Sorry, I forgot to mention that I can only use write(), as was only using printf for my first attempts.
If you want wide chars (16 bit each) as output, use the following code, as suggested by Michael:
wprintf(L"%s", wp);
If you need utf8 output, you have to use iconv() for conversion between the two. See question 7469296 as a starting point.
You need to call setlocale() first and use %ls in printf():
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main(int argc, char *argv[])
{
setlocale(LC_ALL, "");
// setlocale(LC_ALL, "C.UTF-8"); // this also works
wchar_t wp[] = L"Росси́йская Акаде́мия Нау́к";
printf("%ls\n", wp);
return 0;
}
For more about setlocale(), refer to Displaying wide chars with printf
So I am a very beginner to C programming (I have used Ruby, Python and Haskell before) and I am having trouble getting the most simple thing to work in C (probably because of all the manual memory stuff). Anyway, what I am trying to do is (using simple constructs) make a script that just echoes what the user inputs to the console.
e.g. user inputs hi, console prints hi.
This is what I came up with.
Also, I haven't really mastered pointers, so none of that.
// echo C script
int echo();
int main() {
echo();
return 0;
}
int echo() {
char input[500];
while (1) {
if (scanf("%[^\n]", input) > 0) {
printf("%s\n", input);
}
input[0] = 0;
}
return 1;
}
I realize that there is a bunch of bad practices here, like setting a giant string array, but that is just for simplifying it.
Anyway, my problem is that it repeats the first input then the input freezes. As far as I can tell, it freezes during the while loop (1 is never returned).
Any help would be appreciated.
Oh, and using TCC as the compiler.
You don't need an array for echo
#include <stdio.h>
int main(void)
{
int c;
while((c = getchar()) != EOF) putchar(c);
return 0;
}
It's fine that you have such a large string allocated, as long as it's possible for users to input a string of that length. What I would use for input is fgets (read this for more information). Proper usage in your situation, given that you still would like to use the string of size 500, would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int echo(){
char input[500];
while(fgets(input, 500, STDIN)){ //read from STDIN (aka command-line)
printf("%s\n", input); //print out what user typed in
memset(input, 0, strlen(input)); //reset string to all 0's
}
return 1;
}
Note that changing the value of 500 to whatever smaller number (I would normally go with some power of 2 by convention, like 512, but it doesn't really matter) will limit the length of the user's input to that number. Also note that I didn't test my code but it should work.
scanf("%[^\n]", input
Should be:
scanf("%s",input)
Then after your if you should do:
memset(input,0,500);
There are many ways of accomplishing this task however the easiest would be to read from stdin one byte at a time and output that byte to stdout as you process each byte.
Snippet:
#include <stdio.h>
int main( void ) {
// Iterates until EOF is sent.
for ( int byte = getchar(); byte != EOF; byte = getchar() ) {
// Outputs to stdout the byte.
putchar( byte );
}
return 0;
}
Remark:
You must store the byte that you are reading through stdin in an integer. This is because you are not guaranteed that char is signed or unsigned, there are in fact 3 char types in C (char, signed char and unsigned char). Include the limits library to determine whether a char is signed or not in your environment.
You must compile using the C99 standards, otherwise move the declaration of byte outside of the for loop.
When I give the first input, an extra 0 appears before gets() works. But if I remove gets(), then there is no problem. printf() can't be used because it breaks on blank space. Please give any alternative solution or what should I do?
#include <cstdio>
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
long long a,i,t,count;
int op;
char s[10000];
scanf("%lld",&t);
for(i=1;i<=t;i++)
{
gets(s);
a=atoll(&s[7]);
printf("%lld",a);
}
return 0;
}
The scanf() leaves the end-of-line character of the first line in the input stream which is then consumed by gets(). This is a common beginner's error often discussed here.
Recommendations:
Do not mix scanf() routines with gets() routines.
Except for short test programs do not use gets() (instead use fgets()) because with gets() buffer overflows may occur.
You can try adding the '\n' character when you are reading with scanf:
scanf("%lld\n",&t);
for(i=1;i<=t;i++)
{
gets(s);
a=atoll(&s[7]);
printf("%lld",a);
}
Why not:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
long long i;
long long t;
char s[10000];
if (fgets(s, sizeof(s), stdin) == 0)
return 0;
t = atoll(s);
for (i = 1; i <= t; i++)
{
if (fgets(s, sizeof(s), stdin) == 0)
break;
a = atoll(&s[7]);
printf("%lld\n", a);
}
return 0;
}
Amongst other merits, it doesn't:
print stray zeroes,
include C++ code in a purportedly C program,
contain any stray (unused) variables,
use the dangerous gets() function.
It is fair to note a couple of deficiencies:
It would produce bogus output if a data line was not at least 8 characters long; it should check strlen(s) before calling atoll(&s[7])
We'll assume that 10K is longer than any single line it will be given to read so truncated lines won't be a problem, though JSON data sometimes seems to get encoded in files without any newlines and can be humongously long (Firefox bookmark lists or backups, for example, don't even contain a single newline).
I'm sure what you're trying to do here, or what the problem is. But ...
As Greg Hewgill correctly said: NEVER use "gets()". It's a buffer overflow waiting to happen.
You CAN use "fgets()" - and it could easily solve the problem.
While you're at it, why the "scanf()", followed by "gets()", followed by "atoll()"? Can any of these inputs be merged? Or made more consistent?
Where are you checking for a valid conversion from "atoll()"? Why not just use "sscanf()" (and check the return value)?