strcspn() stopping at a period - c

I'm writing a function that should parse a string containing a description of a dice roll, for instance "2*1d8+2". I extract the four values OK when they are integers, but I want to be able to use floats as well for the multiplier and the addition at the end. Things get nasty when I try to parse such a string: "1.8*1d8+2.5".
I have determined that the problem is with the function strcspn. I ask it to parse the input string s (which contains the dice string) and stop at either an asterisk or an 'x':
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
The function should return 3, as the asterisk is at the 4th position. However, it seems to stop on the decimal separator (period) and returns 1.
It's not that I can't continue writing my function without this, as there are other ways to get things done, but still I'm curious why such a thing would happen. Has anyone ever encountered this problem before?
[EDIT]
Nevermind, I've found the answer, and it was my stupidity rather than the compiler playing tricks on me. I used this code:
if (l = strcspn(s,"*x") < strlen(s)) {
...
which returned 1 (or true) because strcspn(s,"*x") < strlen(s) evaluates to true - and was assigned to the l variable. I should have added parentheses:
if ((l = strcspn(s,"*x")) < strlen(s)) {
...
Thanks for your answers nonetheless, particularly #sleske, who made me analyse my code more deeply (which led to finding the answer).

There must be an error somewhere else. I wrote a test program:
#include <stdio.h>
#include <string.h>
void main(){
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
printf("l: %d\n", l);
}
and compiled it with gcc on Linux. On my system, it outputs "3".
Please post a complete, working example that exhibits the problem. Then we'll see...

Your code works just as you posted it for me1.
#include <stdio.h>
#include <string.h>
int main(void) {
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
printf("%zd (%.*s)\n", l, (int)l, s);
return 0;
}
so ross$ ./a.out
3 (1.8)
1. Mac OS X 10.6.4

I'd use sscanf instead of manually finding stop points and parsing myself. You can get your integers and floats easily out of the string with that.

This code:
#include <stdio.h>
#include <string.h>
int main(void)
{
const char * s = "1.8*1d8+2.5";
size_t l = strcspn(s,"*x");
printf("<<%s>> %zd <<%s>>\n", s, l, s+l);
return 0;
}
produces this answer on MacOS 10.6.4 (GCC 4.5.1):
<<1.8*1d8+2.5>> 3 <<*1d8+2.5>>
If your compiler and library does not produce the same answer, get a fixed/upgraded version of the software.
(NB: The 'z' modifier in the printf() format string is a C99 feature - it indicates that the type of the parameter is size_t.)

Related

No output generated from C function returning char*

I am quite new to C so my apologies if this is a straight forward problem but I cannot seem to find my error. My code is as follows
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* makeString(char character,int count)
{
int i;
char* finalString=malloc(count+1);
for(i=1;i<=count;i++)
{
finalString[i]=character;
}
finalString[count]=0;
return finalString;
}
int main()
{
char* string=makeString('*',5);
printf("%s\n",string);
}
I am trying to get an output of the finalString which would be 'character', 'count' number of times. I am not getting any errors or warnings but It is not generating any output. When debugging it runs the loop successfully but does not ever store any character into finalString. Any help appreciated.
As with many programming languages, C uses 0-based indices for arrays. The first element of the character array at finalString is finalString[0], not finalString[1].
Your for loop should go from 0 to count - 1, instead of from 1 to count. The line:
for(i = 1; i <= count; i++)
should instead be:
for(i = 0; i < count; i++)
As your code is now, you have undefined behaviour, because you try to print finalString[0], which is uninitialized. In this case, it seems to be 0 ('\0').
I've ignored the fact that makeString is missing its closing }, since you say this compiles correctly, I assume that's a pasting error.
Arrays in C begin at 0, i.e. the 1st element is finalString[0].
Since you do not set it, it contains garbage, and most probably a NUL which ends the string immediately.
Your loop should look like
for(i=0;i<count;i++)
...
and so on.

Program that finds every other character in the first half of a char array in C

This is the first part of the program and I have a few questions on how parts of it work exactly. Keep in mind this is the first C program I have written. scanf("%d",&numberOfTimes); Why do I need the & and what does it do?
char input[][200]; Is this basically an array of strings or is it something completely different?
#include <stdio.h>
#include <string.h>
char outputs[100];
char input[][200];
int numberOfTimes;
void io(void){
scanf("%d", &numberOfTimes);
for(int i = 0; i < numberOfTimes; i++){
scanf("%s",input[i]);
}
}
This next part of the code is my attempt at actually solving the problem however I suspect that I screwed up the use of a function but I don't know which one or I used something improperly in order to get this result. (I provided example i/o of me code at the bottom).
void stringManipulation(char string[200]){
int strLength = strlen(string);
int number = strLength/2;
for(int i = 0; i <= number; i=i+2){
strcat(outputs,&string[i]);
}
}
int main(void) {
io();
for(int i = 0; i < numberOfTimes; i++) {
stringManipulation(input[i]);
printf("%s\n",outputs);
memset(&outputs[0], 0, sizeof(outputs));
}
return 0;
}
Did I use memset properly? Again I don't understand the use of the &.
Example input:
4
your
progress
is
noticeable
Expected output:
y
po
i
ntc
Output I am getting:
yourur
progressogressress
is
noticeableticeableceable
Thank you for your help.
The & before a variable means that you are referring to the address of the variable, and not the variable value itself. If you don't know about what the address of a variable is : http://www.cquestions.com/2010/02/address-of-variable-in-c.html
char input[][200] is an array of char array (a char array is vulgarized as a string but it ISN'T the TYPE).
Your problem is about your strcat use, you're adding characters that are between string[i] (included) and string[strLength], not only the string[i] character.
Your problem is in strcat:
Your code passes the address and hence you are getting the entire string from that character onward.
strcat(outputs,&string[i]);
Now, change the above code as below:
strcat(output,string[i]);
You'll get the desired output. The problem with your initial code was that you were passing the address and not individual character.
Also, change the for loop in such a way that "<"number and not "<="number.
Let me know if you have any more doubts.

My program is locking up and doesn't seem to do what it's supposed to. What have I done wrong?

I'm a newbie to C programming and I'm up to learning about strings and arrays. My latest challenge is to read in a string, calculate the frequency of each letter and output these including non-letters.
I've written the program but it either locks up or just stops. I can't get it to start the count. Where have I gone wrong?
NB: My lecturer has some particular views on syntax that other people don't necessarily share. I'm going to stick with the syntax that's going to keep my lecturer happy so please don't pick on the "return (0);" at the end of the main function.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
const int COUNT = 27;
const int STRSIZE = 100;
counter[c]++;
c++;
}
else
if((letterfreq[i] < 'a') || (letterfreq[i] > 'z'))
{
counter[26]++;
}
}
}
return;
}
void printFreq(int counter[], int COUNT)
{
int c;
in the string.\n", counter[26]);
return;
}
char promptReset(char reset)
{
printf("Would you like to calculate the letter frequency of another string? (Y/N)\n");
scanf("%c%*c", &reset);
tolower(reset);
return(reset);
}
int main()
{
In your code,
tolower(letterfreq[STRSIZE]);
is overruning allocated memory, which in turn invokes undefined behaviour. Remember, C array index is 0 based.
That said,
I don't see the point of the whole statement here. Maybe you'd want to have a look at the man page of tolower(http://linux.die.net/man/3/tolower) one again.
There is no need to pass COUNT, STRSIZE as arguments to functions.

c variable turning into -17918 when incremented

hi i am making a programming language that will run on the nintendo gameboy in c
which is why you will see some functions like waitpad();
but this question is unrelated the the gameboy librarys
for some reason when ever i try to increment a certain variable in my main.c file:
#include <stdio.h>
#include <gb/gb.h>
#include "convert.h"
#include "display.h"
#include "input.h"
#include "functions.h"
#include "interpreter.h"
unsigned char cnt[5] = {1,2,3,4,5};//cnt is short for counters
unsigned char k = 0;
unsigned char running = 1;
unsigned char memory[2048];
unsigned char code[2048];
int main()
{
Clear_mem();
Clear_code();
while(running == 1) {
display(cnt[0],cnt[1],cnt[2],cnt[3],cnt[4]);
printf("cnt[0] = %d\n", cnt[0]);
cnt[0]++;//turns into -17918
printf("Press Start To Enter Next Character\n");
waitpad(J_START);
code[k] = input();
interpret(code[k]);
k++;
}
return 0;
}
cnt[0] turns into -17918
can anyone see any problem that would cause it to behave this way?
You ask if anyone sees a problem, well - yes, here is a problem:
unsigned char k = 0;
unsigned char running = 1;
unsigned char code[2048];
while(running == 1) {
code[k] = input();
k++;
}
If k >= 2048, then code[k] = ... will cause a memory-override.
After a memory-override, pretty much anything can happens (undefined behavior).
Having said that, the value of k can be larger than 2047 only if CHAR_BIT is larger than 11.
Add #include <limits.h> to your program and make sure that CHAR_BIT is not larger than 11.
You have to convert it to an integer, because that's what you're trying to print:
printf("cnt[0] = %d\n", (int) cnt[0]);
When you're using a variadic function like printf, you have to make sure you're passing the right type. Check your compiler warning settings, new compilers can easily detect these kind of problems.
if you want to print the character value of your character variable you should print it like this:
printf("cnt[0] = %c\n", cnt[0]);
If you print it using %d the expansion of the character to a size of int could be negative for characters over half a character's size (0x80 and up).
If you insist on printing it as an int cast the variable like this:
printf("cnt[0] = %d\n", (int)cnt[0]);

How can I add two strings?

of size 5, that I want to add, according to some conditions that I will impose. Both strings are in the format 00:00. The first string (s1) represents a certain time of departure of a plane, the second one, is how delayed that departure will be...
This is supposed to be done on a 24h clock.
Let's say, for example
s1=10:45
s1=01:50
so first I have to add the 5 and the 0, see if there's a carry out and if the result is under 9, then add the 4 and the 5, see if the result is under 6. If it isn't I subtract 6 to the addition and add the carry out (1) to the 0 and the 1, then I'll add 1 to 0.
5+0=5
4+5=9 9-6=3 carry out:1
0+1+1=2
0+1=1
12:35
What I would like to obtain is s1=12:35
I don't really get how pointers work... I've tried to understand them, but it was in vain...
Can you help me?
I have some ideas that I will post here:
#include <stdio.h>
#include <string.h>
char*add_hours(char s1[], char s2[])
int i;
for(i=4; i>3; i--){
if(s1[i]+s2[i]>9){
strcpy(s1[i], ((s1[i]+s2[i])-10);
strcpy(s1[i-1], (s1[i-1]+1));
}
...
}
the code goes on for a little while, but it repeats itself a few times. So I didn't think I needed to copy it all here. The problem is, he keeps telling me showing this warning:
"warning: passing argument 1 of 'strcpy' makes pointer from integer without a cast
/usr/include/string.h:128: note: expected 'const char * _restrict_' but argument if of type 'int'
And the same thing for the second argument, for every strcpy there is... I understand the error (I think) but I don't know how to correct it...
I may be wrong, but I think you don't want to add like that.
What happens if you have a depature at 00:30 and an arrival at 04:00, but daylight savings happens inbetween?
Populate a time_t structure. Convert that to a time_t. Add your delay, in seconds. Convert that back to a time_t. Print that out using strftme(). Let the time code in the C library deal with all these issues.
First, you should remove the for loop. It just makes 2 iterations and it is confusing.
Then, the first line of your function should be
char * sum = new char[5];
since you probably want to return a new string. It will also make things clearer.
Try to decompose things in order to simplify your problem. Start writing:
int minutes(char * s);
int hours(char * s);
That respectively return the number of minutes and hours expressed in a string.
strcpy expects strings (array of char/char pointer) as its parameters. What you are giving it are single characters. If you want to modify single characters that way, there is no need to use strcpy.
#include <stdio.h>
#include <string.h>
char*add_hours(char s1[], char s2[])
int i;
for(i=4; i>3; i--){
if(s1[i]+s2[i]>9){
s1[i] = (s1[i]+s2[i])-10;
s1[i-1] = s1[i-1]+1;
}
...
}
There are other logical problems with the code, but this should get you started.
#include <stdlib.h>
#include <string.h>
const int MINS_IN_HR = 60;
int StrToMins(char* str)
{
int res = 0;
char temp[3];
temp[2] = '\0';
memcpy(temp, str, 2);
res += atoi(temp)*MINS_IN_HR;
memcpy(temp, str+3, 2);
res += atoi(temp);
return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
char* s1="10:45", *s2="01:50";
int totalMins = StrToMins(s1) + StrToMins(s2);
printf("%d:%d", totalMins / MINS_IN_HR, totalMins % MINS_IN_HR);
return 0;
}

Resources