Newline Constants in C - c

My code:
#include <stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE ='\n';
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
In the above code the output:
value of area: 50
Process returned 0 (0x0) execution time : 2.909 s
Press any key to continue.
There is a new line inserted, but when I change NEWLINE="\n" despite knowing it is a char type, there is no error prompted by the compiler and no newline printed out. Why???
Also, I modified my code as,
#include <stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE ='\n';
const char k="hjk";
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
printf("%c", k);
return 0;
}
The output is only the area calculated and the new line but k is not printed out. I also find this very weird! Can you please give suggestions?
Please be kind enough with the suggestions and point out my mistakes because I am a beginner at C.

The problem is that you are trying to save a string as a char, so you have to change const char k = "hjk" to const char k[]="hjk" and print it using %s instead of %c.
#include<stdio.h>
int main() {
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE ='\n';
const char k[]="hjk";
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
printf("%s", k);
return 0;
}
Some clarification: if you save a "string" without specifying that it is an array of characters char[], if you try to print it as a char %c a warning would be generater (warning: incompatible pointer to integer conversion initializing 'const char' with an expression of type 'char [4]') and if you try to print it as a array of characters %s (string) you are going to receive a segmentation fault.

when I change NEWLINE="\n" despite knowing it is a char type, there is no error prompted by the compiler
const char NEWLINE = "\n"; is invalid C. The reason why it is invalid is explained in detail here: "Pointer from integer/integer from pointer without a cast" issues
The compiler is not required to produce an "error", but it is required to produce some sort of diagnostic message. See What must a C compiler do when it finds an error?
Why your compiler decided to spew out a binary regardless of getting fed invalid C is anyone's guess. You have to ask the people who made the compiler. In case of gcc, you won't find an answer, because this is completely undocumented behavior.
And therefore, any output you get from such a "non C" program is also completely non-deterministic, unless a compiler documented the behavior among non-standard compiler extensions. gcc did not.
Similarly, const char k="hjk"; is also invalid C.

k seems an array of char.
Try to use:
const char k[] = "something";
printf("%s", k);

The statement const char k="hjk"; is not valid C code. Apparently, your compiler accepts it and assigns the memory address where the literal string "hjk" begins to k. Both a memory address and a char are implemented as integer numbers, so the memory address is interpreted as the numeric code for a character.
Because k is now, most likely, an unprintable character, printf("%c", k); will print nothing.
Exactly the same happens when you do const char NEWLINE ='\n';.

Related

Error invalid operands to binary expression

I've been working on readability and I really am stuck as to what I've done wrong/what I'm missing.
#include <stdio.h>
#include <math.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main() {
string text = get_string("Text: ");
int sentences = 0;
int numberOfCharacters = strlen(text);
string characters[numberOfCharacters];
int words = 0;
for (int i = 0; i == numberOfCharacters; i++) {
if (isspace(characters[i]) == 0) {
words ++;
}
}
for (int i=0; i < numberOfCharacters; i++) {
if (text[i]=='.') {
numberOfCharacters++;
}
}
int averageWords = characters / words * 100;
int index = 0.0588 * round(characters) - 0.296 * round(sentences) - 15.8;
printf("Grade %d \n", index);
}
The error I get from that, using help50, is: readability.c:26:35: error: invalid operands to binary expression ('string [numberOfCharacters]' and 'int')
Which I don't understand, so please if possible help :)
In cs50 string is a typedef of char*, so what you have there is:
char *characters[numberOfCharacters];
Which is an array of pointers, they are not initialized in any way, in your next statements you accessing these unitialized values and you are passing an incompatible argument to isspace.
Furthermore, the expression:
int averageWords = characters / words * 100;
Is odd, you're dividing an array of pointers to char (wich decays to a pointer, but that's beside the point), by an int. That's where the error stems from, but you need to correct the rest.
Not to mention round(characters) which is also very strange, that function expects a double argument, but again, you are passing to it an array of pointers.
The name string is defined as an alias for the type char *. So this declaration
string characters[numberOfCharacters];
is equivalent to the declaration
char * characters[numberOfCharacters];
So in this expression
isspace(characters[i]) == 0
the argument characters[i] has the type char * while the function expects an argument of the type int.
So you need at least to declare
char characters[numberOfCharacters];
But in any case this loop
for (int i = 0; i == numberOfCharacters; i++) {
if (isspace(characters[i]) == 0) {
words ++;
}
}
does not make a sense because the array characters was not initialized.
It seems within this loop you were going to use text instead of characters.
This expression
int averageWords = characters / words * 100;
is entirely wrong and does not make a sense. You are trying to divide a pointer ( after implicit conversion the array characters to a pointer to its first element) by an integer. But such an operation is not defined for pointers.
So it is unclear what the program does.
First Issue:
string is defined as char * so this is wrong:
string characters[numberOfCharacters];
That is giving you an array of strings, not a string of length numberOfCharacters
Change that to this:
char characters[numberOfCharacters];
Second Issue:
characters is uninitialized when first used, you could of meant to use text instead in the loop
Third Issue:
Performing math (round(characters) and characters / words * 100) on a string or array is certainly wrong and makes no sense, so I am not sure what you are attempting to do here
I reviewed the clear issues, but since it is unclear what your program is trying to do, I cannot provide further feedback

Why does the GCC Compiler allows us to declare zero length strings (directly) and negative length strings (indirectly)?

/*implementation of strrev i.e. string reverse function*/
#include<stdio.h>
#include<string.h>
/*length of the string i.e. cells in the string*/
static const unsigned int MAX_LENGTH = 100;
//static const int MAX_LENGTH = -100;
/*reverses the string*/
void reverseString(char[]);
/*swaps the elements in the cells of a string*/
void swap(char[], int, int);
/*runs the program*/
int main()
{
char string[MAX_LENGTH];
//char string[0]; //no error!
//char string[-1]; //error!
gets(string);
reverseString(string);
printf("\n%s", string);
return 0;
}
void reverseString(char string[])
{
int i;
for(i = 0; i < (strlen(string) / 2); i++)
{
swap(string, i, (strlen(string) - 1 - i));
}
}
void swap(char string[], int i, int j)
{
int temp = string[i];
string[i] = string[j];
string[j] = temp;
}
Look at the main function. If you replace the first line "char string[MAX_LENGTH];" with "char string[-1];", the compiler shows error. (because string of negative length makes no sense). However, if you replace the 7th line of this code (where I declared const MAX_LENGTH) with the code written in comments in line 8 (in which MAX_LENGTH is assigned a -ve value), there is no compilation error. Why?
Also, why there is no error in declaring zero length string. How does zero length string makes sense to compiler but not a negative length string?
Because it's not the same thing.
In the first case, you're defining an array, using a fixed, compile-time size
In the second case, you're defining a variable length array or VLA.
The compiler does the allocation at run time in the second case (with this -100 value it isn't going to end well), because the const isn't really a constant in C, it just tells the compiler you aren't to change the value (and also allows some optimizations). So the result is undefined behaviour (more here: Declaring an array of negative length)
If you want the same behaviour use a #define
#define MAX_LENGTH -100 // will raise a compilation error
or as suggested in comments, an enumerated constant:
enum { MAX_LENGTH = -100 }; // will raise a compilation error
If you want to protect your declarations, use assert
assert(MAX_LENGTH > 0);
char string[MAX_LENGTH];
As for the zero-length element, no need to repeat what's already been answered: What's the need of array with zero elements? (in a nutshell, it's useful at the end of a structure to be able to have varying length)

Printing integers passed as arguments in function in C

I am very new to C programming and having trouble compiling what should be a very simple function. The function, called printSummary, simply takes 3 integers as arguments, then prints some text along with those integers. For example, if hits=1, misses=2, and evictions=3, then printSummary(hits,misses,evictions) should print the following:
hits:1 misses:2 evictions:3
Here is the code I'm using. Thanks in advance for any advice.
#include<stdio.h>
void printSummary(int hits, int misses, int evictions)
{
printf('hits: %d\n');
printf('misses: %d\n');
printf('evictions: %d\n');
}
int main()
{
int hit_count = 1;
int miss_count = 2;
int eviction_count = 3;
printSummary(hit_count, miss_count, eviction_count);
return 0;
}
Compiling this code gives me several warnings, but no errors. When I run the code, I get a segmentation fault. Like I said, I am fairly new to C so there is most likely a simply solution that I am just missing. Thanks in advance for any advice.
Make the below changes .
printf("hits: %d\n",hits);
printf("misses: %d\n",misses);
printf("evictions: %d\n",evictions);
printf has a
int printf(const char *format, ...)
prototype. So in the first argument you can pass format specifiers and in the next provide the actual variables/values to be printed out
errors are:
void printSummary(int hits, int misses, int evictions)
{
/* Name: printf
Prototype: int printf (const char *template, ...)
Description:
The printf function prints the optional arguments under the
control of the template string template to the stream stdout.
It returns the number of characters printed,or a negative value if
there was an output error.*/
printf("hits: %d\n", hits); // don't use ' it is used only for char variable for example: char a = 'c';
printf("misses: %d\n", misses);
printf("evictions: %d\n", evictions);
}
Your printf function is not being called correctly. You have to include the integers needed to print:
printf("hits: %d\n", hits);
printf("misses: %d\n", misses);
printf("evictions: %d\n", evictions);
Read more about the printf function here.

diffculty in entering strings in C using pointer

The following program works in gcc but on giving the value of T = 6, this program continues and does not end on asking for input strings. Any help guys if you recognise whats wrong with this program?
int main()
{ int T,i,j;
char *strings[T];
printf("Enter the Number of Strings to Reverse : \n");
scanf("%d ",&T);
for(i=0;i<T;i++)
{ strings[i] = (char *)malloc(100*sizeof(char));
scanf("%s\n",strings[i]);
}
for(i=0;i<T;i++)
{printf(" The String %d is : %s\n",i+1,strings[i]);
}
return 0;
}
T is not initialised (Remember in C++, local scope variables are not automatically initialised) :
int T= 6;
T is not initialized inside main() therefore has an undefined value.
char *strings[T] creates an array of char * pointers of an undefined length.
Fix this using:
int T=6;
Or, given T is in fact constant:
const int T=6
or perhaps better
#define T 6
Feel free to use a more mnemonic name than T.

incompatible pointer to integer although using char of arrays

I'm new to the world of C programming, and I as trying to code a primitive, terminal-based version of the "Hangman" game.
One of the steps doing this (or at least the way I am working on), is to create a second char array (next to the original char array that stores the word one needs to guess), filled with "*" for every Char of the original array, and display it. Although the rest of the programming part is not there yet (since I am not finished with it yet), I doubt it is relevant for now (however I allready know how to proceed, that is if I weren't bothered by some error-messages)....
Here's the code I have so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
void hiddenArray(char array[]);
char *secretWord;
char *arrayCover;
char letter;
int main(int argc, char *argv[]){
secretWord = "Test";
printf("Welcome to the Hangman!\n\n");
hiddenArray(secretWord);
printf("What is the hidden Word?: %c\n", *arrayCover);
printf("Guess a letter\n");
scanf("%c", &letter);
}
void hiddenArray(char array[]){
int size,i;
size = sizeof(*array);
for (i=0;i<size-1;i++){
*(arrayCover+i) = "*";
}
}
Now I have two issues... the first one:
I don't understand the error message I am getting after compilation:
pendu.c:41:19: warning: incompatible pointer to integer conversion assigning to 'char' from 'char [2]' [-Wint-conversion]
*(arrayCover+i) = "*";
^ ~~~
1 warning generated.
And my second question: the second Array created, filled with "*" is not being displayed, what did I do wrong?
I'd love for some help, cheers!
Your program have some errors to be corrected .
1) Your *arraycover is pointing to some unknown value, You have not initialized it.
2) sizeof(*array) should be sizeof(array)
3) *(arrayCover+i) = "*" should be *(arrayCover+i) = '*';
I suggest you not to create too many global variables when you dont really need them
Create char secretWord[100] = "Test" instead of char *secretWord
Try this
size = sizeof(arrayCover)/sizeof(char);
for (i=0;i<size-1;i++){
*(array+i) = '*';
}
Despite of all these, I think you need to allocate memory for arrayCover
arrayCover = malloc(sizeof(char) * number_of_elements);
"*" is a string. Use '*' instead to get the char.
"*" is a string which also contains \0 also, resulting to 2 characters. Instead use '*' which is just a character.
The function hiddenArray has the formal argument array which need to be used locally instead of arrayCover as below,
void hiddenArray(char array[]){
int size,i;
size = sizeof(array)/sizeof(array[0]);
for (i=0;i<size-1;i++){
*(array+i) = '*'; /* Or array[i] = '*' */
}
}

Resources