Is there a missing code on the isupper function? - c

#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <math.h>
// Prototype
string Get_text(void);
char isupper(ch);
int main(void)
{
string text = Get_text();
printf("%s\n", text );
}
// Prompt the user for text
string Get_text(void)
{
string n;
do {
n = get_string("Text: ");
}
while (n >= 0);
// Letters, Words, & Sentences
char ch = 'A';
}
I encountered an error when I ran my code. It point out to line 9 where I implemented the isupper function to check if the letters are capital. I even included an extra parenthesis on the isupper before the parenthesis on char but there's still errors. P.S I'm not yet done with the code. I'm reviewing how the isupper function works.

isupper was once a macro. Never declare it. #include <ctype.h> does the right thing.
If the offending declaration were for something other than isupper I would answer rather as follows:
char isupper(ch);
is bad syntax because it should be (type argumentname) in parenthesis. It would rather be as it appears in the man page (taking the luxury of correcting the type)
int isupper(int ch);
but as I said don't actually do this because of macro fun for the builtins in ctype.h.
Anyway, you're coding in c (from the tag) so there's no stock string type. This is not a compilable fragment; thankfully the line you're asking about occurs early enough that we can tell anyway what the problem is.

The isupper identifier coincides with a <ctype.h> function/macro that is included in the standard library.
As there's an already introduced prototype for the isupper function (int isupper(int ch);) that doesn't match the one you have used, it is giving you an error.
Simply call it otherwise (more if you plan to use the <ctype.h> routines) and not isupper.

Related

Expected encoding of wcwidth() argument

I'm trying to find out what the expected encoding of wcwidth() argument is.
The man page says absolutely nothing about this, and I wasted hours trying to
find out what it is. Here's an example, in C:
#include <stdio.h>
#include <wchar.h>
void main()
{
wchar_t c = L'h';
printf("%d\n", wcwidth(c));
}
I want to know how should I encode this character literal so that this program
prints 2 instead of -1.
Here's a Rust example:
extern "C" {
fn wcwidth(c: libc::wchar_t) -> libc::c_int;
}
fn main() {
let c = 'h';
println!("{}", unsafe { wcwidth(c as libc::wchar_t) });
}
Similarly I want to convert this character constant to wchar_t (i32) so that
this program prints 2.
Thanks.
UPDATE: Sorry for my wording, I made this sound specific to C's long char literals. I want to encode character literals in any language as a 32-bit int so that when I pass it to wcwidth I get a right answer. So my question is not specific to C or C's long char literals.
UPDATE 2: I'd also be happy with another function like wcwidth that is better specified (and maybe even platform independent). E.g. one that takes UTF-8 encoded character and returns number of cols needed to render it in a monospace terminal.
You need to add support for _XOPEN_SOURCE and also you need to set your locales.
Try this:
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <locale.h>
#include <wchar.h>
int main(void)
{
setlocale(LC_CTYPE, "");
wchar_t c = L'h';
printf("%d\n", wcwidth(c));
return 0;
}

EOF block while loop in c

I'm trying to make a code in c, that simply write disk c information in txt file with cmd comand "Wmic logicaldisk get" but i need only numbers instead (size 4294931).
So i pick this output and put it into a txt file to get only number in input.(I know it's quite strange).
This is the full code:
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <ctype.h>
int main()
{
system("wmic logicaldisk get size> test.txt");
unsigned char symb;
FILE *FileIn;
FileIn = fopen("test.txt","rt");
int getc(FILE *stream);
while (( symb = getc(FileIn)) !=EOF)
{
if( isdigit(symb))
{
printf("%C", symb);
}
}
printf("test"); //for debug
}
the code work but can't exit the loop while, the number it's printed correctly but the next comands aren't executed(so the pritnf test isn't executed).
There are three things going on in your code that's wrong.
You redeclare a prototype for getc. You should not do that, since your declaration might not be the same as the official standard declaration.
The getc function returns an int. That is because EOF is an int constant, with the value -1. And ((unsigned char) -1) != -1. This is because the unsigned char value -1 is really 255 and that is not anywhere equal to -1. The variables you use together with getc (or any similar function) must be an int.
The printf format specifier "%C" (with an upper-case C) is not a standard format specifier. It is an Microsoft Visual C++ extension and is for wide characters of type wchar_t. Since your variable symb is not the correct type matching the format specifier you will have undefined behavior. For a narrow character like yours you should use lower case c.

Toggle the cases means capital to small and small to capital

Like if your file has the following text: CompuTEr. Then after running your code the content of the file should be: cOMPUteR!
But problem is only one character which is a. It is not changing into Captial A.
#include<stdio.h>
#include<conio.h>
#include <ctype.h>
int main()
{
char name[100];
int loop;
printf("Enter any Sting: ");
gets(name);
for (loop=0; name[loop] !=0; loop++)
{
if(name[loop]>='A' && name[loop]<='Z')
name[loop]=name[loop]+32;
else if(name[loop]>'a' && name[loop]<='z')
name[loop]=name[loop]-32;
}
printf("\nConvert case of character : %s",name);
return 0;
}
Change
else if(name[loop]>'a' && name [loop]<='z')
To
else if(name[loop]>='a' && name [loop]<='z')
And Never ever use gets(). It is dangerous because it dosen't prevent buffer overflows. Use fgets() instead:
fgets(name,sizeof(name),stdin);
There are many problems with your code:
#include<stdio.h>
Use proper spacing: #include <stdio.h>.
While most spacing is not required, consistent use of spaces and indentation greatly enhances code readability and reduces the number of bugs. If you use sloppy style, you probably also use buggy algorithms and careless constructs. Bugs will have more places to hide. C is a very sharp tool, it is unforgiving with the careless.
#include<conio.h>
This header is an obsolete, Microsoft specific thing. It is not required here.
#include <ctype.h>
ctype.h defines the right functions for your assignment, but you don't even use them!
int main()
Define main as int main(void) or int main(int argc, char *argv[])
{
char name[100];
int loop;
printf("Enter any Sting: ");
So this whole thing was just a sting? Interesting lapsus!
gets(name);
Definitely never ever use gets! If the user types more than 99 characters at the prompt, gets will cause a buffer overflow as it cannot determine the size of name. This buffer overflow will most likely cause the program to crash, but careful exploitation of such a flaw can allow an attacker to take control of the computer. This is a very good and simple example of a security flaw. scanf is more complicated, inefficient and difficult to use safely in this context, as in most. Just use fgets and handle the trailing '\n' appropriately.
for (loop=0; name[loop] !=0; loop++)
The common idiom for this loop is to use an index variable called i. Naming it loop is confusing and verbose. The comparison to 0 could be written more simply as name[loop] is your teacher condones it, or name[loop] == '\0' to make it clear that you are comparing characters.
{
if(name[loop]>='A' && name[loop]<='Z')
You should use isupper to test for upper-case. Comparing explicitly to character values 'A' and 'Z' is non portable and error prone as you don't seem to get your comparisons right.
name[loop]=name[loop]+32;
You are assuming ASCII or similar encoding. This dirty trick is non portable, confusing and error prone. Just use the tolower function.
else if(name[loop]>'a' && name[loop]<='z')
Same remark as above. Your code is buggy. Proper use of spacing and less verbose index name should make the bug more obvious:
else if (name[i] > 'a' && name[i] <= 'z')
Use islower for both portability and reliability.
name[loop]=name[loop]-32;
See above. toupper was designed for this purpose.
}
printf("\nConvert case of character : %s",name);
Fix the broken English. Also add a '\n' at the end of the format string. Some systems will not even output anything if you don't.
return 0;
}
Proofing your homework online is only useful if you learn from it. I hope you did!

How to find the built-in function to deal with char16_t in C?

Please tell what is the char16_t version for the String Manipulation Functions
such as:
http://www.tutorialspoint.com/ansi_c/c_function_references.htm
I found many references site, but no one mentioned that.
Especially for printing function, this is that most important, because it help me to verify whether the Manipulation function is work.
#include <stdio.h>
#include <uchar.h>
char16_t *u=u"α";
int main(int argc, char *argv[])
{
printf("%x\n",u[0]); // output 3b1, it is UTF16
wprintf("%s\n",u); //no ouput
_cwprintf("%s\n",u); //incorrect output
return 0;
}
To print/read/open write etc.., you need to convert to 32-bit chars using the mbsrtowcs function.
For ALL intents and purposes, char16_t is a multi-byte representation, therefore, one need use mbr functions to work with this integral type.
A few answers used the L"prefix" which is completely incorrect. 16-bit strings require the u"prefix".
The following code gets you everything you need to work with 8, 16, and 32-bit string representations.
#include <string.h>
#include <wchar.h>
#include <uchar.h>
You can Google the procedures found in <wchar.h> if you don't have manual pages (UNIX).
Gnome.org's GLib has some great code for you to drop-in if overhead isn't an issue.
char16_t and char32_t are ISO C11 (iso9899:2011) extensions.
wprintf and its wchar colleagues need to have th format string in wchar too:
wprintf( L"%s\n", u);
For wchar L is used as a prefix to the string literals.
Edit:
Here's a code snippet (tested on Windows):
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <wchar.h>
void main()
{
wchar_t* a = L"α";
fflush(stdout); //must be done before _setmode
_setmode(_fileno(stdout), _O_U16TEXT); // set console mode to unicode
wprintf(L"alpha is:\n\t%s\n", a); // works for me :)
}
The console doesn't work in unicode and prints a "?" for non ascii chars. In Linux you need to remove the underscore prefix before setmode and fileno.
Note: for windows GUI prints, there already proper support, so you can use wsprintf to format unicode strings.

C symbolic constant + strcture

Given the following snippet of code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 15
typedef struct{
int touchdowns;
int interceptions;
int tackles[MAX_SIZE + 1]; //this is the line in question
}stats;
The question posed to me was, "Why does this line [denoted above] add 1 to the possible number of tackles?"
----NOT why would one want too, but how/why does it work. Why is it valid code in otherwords, not necessarily valid logic. -Clarification
I'm unsure of how to answer this question in detail. Any help would be appreciated.
As Armin pointed out, the token MAX_SIZE is replaced by the preprocessor. But for clarification, that's not why it works/compiles in the end. The actual requirement for this to compile is, that the array size is a constant integral expression, which applies to the code in question.
MAX_SIZE is replaced by 100 when code is compiled and the line becomes
int tackles[100 + 1];
which is the same as
int tackles[101];
From documentation:
To define preprocessor macros we can use #define. Its format is:
#define identifier replacement
When the preprocessor encounters this directive, it replaces any occurrence of identifier in the rest of the code by replacement. This replacement can be an expression, a statement, a block or simply anything. The preprocessor does not understand C++, it simply replaces any occurrence of identifier by replacement.
#define TABLE_SIZE 100
int table1[TABLE_SIZE];
int table2[TABLE_SIZE];
After the preprocessor has replaced TABLE_SIZE, the code becomes equivalent to:
int table1[100];
int table2[100];
Probably because tackles is an array terminated by a terminator value (such as -1), similar how C strings are terminated by the null character. Note how the structure has no member denoting the number of tackles.

Resources