this part of the code is just a bit of a task I was solving in school. All I should do is open file oblici.txt and guess the figure inside (10x10 field consisting of # and - showing the figure). So, I misscalculated size of the string s and instead of 11 I allocated only 10 spaces. The problem is, it wont count over 2. Well, I found a solution (s[11] and it works) but cant figure out why is this a problem. Not just why is it a problem, I know overflow is not a good thing, but how in hell it can write 0 (instead of 9) when I have the if(b>0) which cleary eliminates the possibility of writing 0 inside the array x. My only guess was that '\0' has value of 0 and it gets written inside of b but that just doesnt make sense...
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp=NULL;
int x[10],i,j=0,b=0;
char s[10];
fp=fopen("c:\\temp\\oblici.txt","r");
if (fp==NULL)
exit(1);
while(fscanf(fp,"%s",s)!=EOF){
for(i=0;i<10;i++)
if(s[i]=='-')
b++;
if(b>0)
x[j++]=b;
b=0;
}
for(i=0;i<j;i++)
printf("%d ",x[i]);
fclose(fp);
}
Where oblici.txt is:
It is because there is a newline (\n) character at the end of each line, thus in total 11 characters per line. Using 10 messes up the calculation.
As a tip, btw, avoid not using {} around if, for and while statements as it is a really common way to introduce bugs!
Related
I'm quite new to dynamic memory allocation in general.
I've been looking for an error in this code for about 6 hours in the last 3 days now, it's driving me crazy, that's why I've decided to ask for help here.
Here's the code:
char ch;
char* line=(char*)calloc(1, sizeof(char));
if(input!=NULL) {
for(int num=1; (ch=fgetc(input)) != EOF; num++) //input is the pointer to the in file
if(ch!=' ') {
line=(char*)realloc(line, sizeof(char)*num+1);
strcat(line, &ch);
}
else
break;
}
I'm trying to read from a file the first of two whitespace-separated words, where the total size is not predetermined (I'll need this to read even more from the file so it's important, this was "just to try").
This is for a single line, not multiple lines (char** I think would be used in that case), and the idea was to allocate the first character of the line and set it to zero, then reallocate the memory incrementing its size by one character.
If I "num++", it crashes; if I don't, its output will be, instead of "Nole", this: N☺o☺l☺e☺ (output is after the loop; how does it even increase if num remains the same?). I checked the ASCII codes and this is what I get: 78 1 111 1 108 1 101 1; there is a '1' after every character, which is THE SAME value as "num" (in fact, if num==2, then I get '2's instead of '1's). I've tried it with different compilers and different machines but I always get the same result and I cannot explain why.
I'm really going crazy, also because I'm gonna have an exam in about two weeks and this is basically the only thing I haven't learned yet among all the required topics.
Thank you so much in advance 😿
EOF is an int so you must use int ch;
As mentioned in comments, you pass a single ch to strcat and not a null terminated string, so it will go haywire. Quick fix: strcat(line, (char[2]){ch,'\0'});.
Or if you add a counter, you could just do line[count] = ch; which is much more efficient. Though in that case you'll have to remember to append the null terminator manually in the end.
Also, sizeof(char) is always 1 by the very definition of sizeof, so it's just a needlessly bloated way of writing 1.
I'm trying to arrange this character array that only contains digits,it prints the same array with the order I input it without any change , i tried using type casting in the if statement, it gave me correct results when running but it wasn't accepted by the online judge.what is the fault here and why isn't my second solution accepted?
#include <stdio.h>
#include <string.h>
int main() {
char x[101];
scanf("%s",x);
int l,i,j ;
l = strlen(x);
char temp ;
for(i=0;x[i];i++)
{
for( j=i ; x[j] ; j++){
if('x[j]'<'x[i]') //(int)x[j] and (int)x[i] didn't work on the
//online judge
{
temp=x[i];
x[i]=x[j];
x[j]=temp;
}
}
}
printf("%s",x);
return 0 ;
}
I have no idea why there are quotes around the array elements, but that is not doing what you think, the comparison is happening because a multicharacter string is evaluated to an integer value which is implementation defined, hence the if statement is always comparing the same values, which means that it will always give the same result, you need to remove the quotes
if (x[j] < x[i])
Also, i'd recommend specifying the length of the array to scanf() and checking that it successfuly read the value, like this
if (scanf("%100s", x) != 1)
return -1; /* Perhaps EOF, i.e. you pressed Ctrl+D or (Ctrl+Z MS Windows) */
If you don't check your program will invoke undefined behavior, and if here it doesn't hurt any critical part of your simple program, if you don't learn to do it, then you will have a lot of hard do debug bugs in the future when you write a bigger program.
The quotes in your if statement evaluate to multicharacter constants, which in my compiler (VC++ 2013) happen to be 785B6A5D and 785B695D respectively, which are the ASCII codes of these characters glued together. Thus that if never executes. Also, what do you mean by "didn't work"? Did you get a compilation error? If yes, what did it say? Otherwise you may have exceeded the time limit since bubble sort is extremely slow.
I've been reading through SO for the past couple of days trying to figure this out, I am stumped. I want to read in two 32 bit byte arrays (from stdin, input will be hex) and xor them, then print the result.
So far I've tried using scanf, fgets, and gets. My thought was to read the large hex numbers into a char buffer and perform the xor in a for loop until I hit an EOL (with fgets) or a null terminator. So far my output is not even close. I tried lots of variations, but I will only post my latest fail below. The challenge I've been trying to complete is: http://cryptopals.com/sets/1/challenges/2/
I am trying it in C because I'm really trying to learn C, but I'm really getting frustrated with none of these attempts working.
#include <stdio.h>
#include <math.h>
int main()
{
char buff1[100];
char buff2[100];
char buff3[100];
int size = sizeof(buff1);
puts("Enter value\n");
fgets(buff1, size, stdin);
puts(buff1);
puts("Enter value\n");
fgets(buff2, size, stdin);
puts(buff2);
for (int i = 0; i != '\n'; i++) {
buff3[i] = buff2[i] ^ buff1[i];
printf("%x", buff3[i]);
}
return 0;
}
When using sizeof() it should be used with types, not data. For instance if you want space for 100 chars, you need to find the sizeof(char) and then multiply by 100 to find out how many bytes you need and that goes into the buffer. A char is usually a byte so expect 100 bytes. fgets() will work but I prefer to use this
int getchar()
Just stop when the the user
enters a newline/terminator character. Since you don't know how many characters will come in from stdin, you
need to dynamically increase the size of your buffer or it will overflow. For the purposes of this question you can just make it a very big array, check to see if its about to overflow and then terminate the program. So to recap the steps.
1.) Create a big array
2.) While loop over getchar() and stop when the output is the terminator, take note of
how many chars you read.
3.) Since both buffers are guaranteed to have equal chars make your
final array equal to that many chars in size.
4.) For loop over getchar() and as the chars come out, xor them with the first array
and put the result into the final array. You should try doing this with 1 array
afterwards to get some more C practice.
Good luck!
EDIT:
fgets() can be used but depending on the implementation it is useful to know how many chars have been read in.
#include <string.h>
#include <ctype.h>
static inline unsigned char hc2uc(char d){
const char *table = "0123456789abcdef";
return strchr(table, tolower(d)) - table;
}
...
for(int i=0;buff1[i]!='\n';i++){
buff3[i]=hc2uc(buff2[i])^hc2uc(buff1[i]);
printf("%x",buff3[i]);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am having a lot of trouble starting my project. Here are the directions:
"Complete counts.c as follows:
Read characters from standard input until EOF (the end-of-file mark) is read. Do not prompt the user to enter text - just read data as soon as the program starts.
Keep a running count of each different character encountered in the input, and keep count of the total number of characters input (excluding EOF)."
The format my professor gave me to start is: `
#include <stdio.h>
int main(int argc, char *argv[]) {
return 0;
}
In addition to how to start the problem, I'm also confused as to why the two parameter's are given in the main function when nothing is going to be passed to it. Help would be much appretiated! Thank you!
`
Slightly tricky to see what you're having trouble with here. The title doesn't form a complete question, nor is there one in the body; and they seem to be hinting at entirely different questions.
The assignment tells you to read characters - not store them. You could have a loop that only reads them one at a time if you wish (for instance, using getchar). You're also asked to report counts of each character, which would make sense to store in an array. Given that this is of "each different character", the simplest way would be to size the array for all possible characters (limits.h defines UCHAR_MAX, which would help with this). Remember to initialize the array if it's automatically allocated (the default for function local variables).
Regarding the arguments to main, this program does not need them, and the C standard does allow you to leave them out. They're likely included as this is a template of a basic C program, to make it usable if command line arguments will be used also.
For more reference code you might want to compare the word count utility (wc); the character counting you want is the basis of a frequency analysis or histogram.
This should give you a start to investigate what you need to learn to complete your task,
Initially declare a character input buffer of sufficient size to read chars as,
char input[SIZE];
Use fgets() to read the characters from stdin as,
if (fgets(input, sizeof input, stdin) == NULL) {
; // handle EOF
}
Now input array has your string of characters which you to find occurrence of characters. I did not understand When you say different characters to count, however you have an array to traverse it completely to count the characters you need.
Firstly, luckily for you we will not need dynamic memory allocation at all here as we are not asked to store the input strings, instead we simply need to record how many of each ascii code is input during program run, as there a constant and finite number of those we can simply store them in a fixed size array.
The functions we are looking at here (assuming we are using standard libs) are as follows:
getchar, to read chars from standard input
printf, to print the outputs back to stdout
The constructs we will need are:
do {} while, to loop around until a condition is false
The rest just needs simple mathematical operators, here is a short example which basically shows a sample solution:
#include <stdio.h>
int main(int argc, char *argv[])
{
/* Create an array with entries for each char,
* then init it to zeros */
int AsciiCounts[256] = {0};
int ReadChar;
int TotalChars = 0;
int Iterator = 0;
do
{
/* Read a char from stdin */
ReadChar = getchar();
/* Increment the entry for its code in the array */
AsciiCounts[ReadChar]++;
TotalChars++;
} while (ReadChar != EOF);
/* Stop if we read an EOF */
do
{
/* Print each char code and how many times it occurred */
printf("Char code %#x occurred %d times\n", Iterator, AsciiCounts[Iterator]);
Iterator++;
} while (Iterator <= 255);
/* Print the total length read in */
printf("Total chars read (excluding EOF): %d", --TotalChars);
return 0;
}
Which should achieve the basic goal, however a couple of extension exercises which would likely benefit your understanding of C. First you could try to convert the second do while loop to a for loop, which is more appropriate for the situation but I did not use for simplicity's sake. Second you could add a condition so the output phase skips codes which never occurred. Finally it could be interesting to check which chars are printable and print their value instead of their hex code.
On the second part of the question, the reason those arguments are passed to main even though they are ignored is due to the standard calling convention of c programs under most OSes, they pass the number of command line arguments and values of each command line argument respectively in case the program wishes to check them. However if you really will not use them you can in most compilers just use main() instead however this makes things more difficult later if you choose to add command line options and has no performance benefit.
I'm trying to get numbers from stdin to an array. the first number in stdin is the number of elements in the array (the number can be any int).
I did this to get the first number:
while(c=getchar()!=' '){
n*=10;
n+=atoi(c);
}
And then created an array of size n.
Now I need to go through all the rest
while(c=getchar()!=EOF)
and add numbers to the array. The numbers are separated by \t and sometimes \n as well.
How would I do that? I've been thinking for an hour and still haven't got a working code.
Any help?
Thanks!
Unless you're feeling particularly masochistic (or can't due to homework requirements), you'd normally do it using scanf:
int n;
int *numbers;
scanf("%d", &n);
numbers = malloc(n * sizeof(*numbers));
for (int i=0; i<n; i++)
scanf("%d", &numbers[i]);
For more robust error handling, you frequently want to read a line at a time using fgets, then parse that into individual numbers using sscanf (or something similar).
As an aside: no you should not cast the return from malloc to int *. It's neither necessary nor desirable in C. Just #include <stdlib.h>, and assign the result as shown above. If your compiler is giving you a warning (or error) about a conversion, that means one of two things is happening: either you've forgotten to #include <stdlib.h> as required, or else you're actually compiling as C++. If you're writing C++, write real C++, which means you shouldn't be using malloc at all.