This is my palindrome code in c:
#include <stdio.h>
#include <stdlib.h>
char toUpperCase(char c) {
if (c > 'Z') {
c -= 32;
}
return c;
}
int isPalindrom(char word[40]) {
int count = 0;
int letterCount = 0;
char lettersOnly[40];
for (int i = 0; i < 40; i++) {
char current = word[i];
if (current == '\n' || current == '\0') {
count = i;
break;
}
if ((current >= 'A' && current <= 'Z') || (current >= 'a' && current <= 'z')) {
lettersOnly[letterCount] = current;
letterCount++;
}
}
return 1;
}
It gives me an error that I set the variable "count" but didn't use it. I clearly used it tho.
How can I resolve this?
Your code only sets the value of count (count = i in the loop). It never reads this value, and thus it's safe to say that the program would have worked the same way had it been removed altogether.
Related
I am trying to find solution how to add '\0' at the end of string (array of characters in C ).
I already have array "number" which is generated from for loop.
int i=0;
int j=0;
char s[] = "123.45e-10";
while (s[i] != '\0') {
if (isdigit(s[i]) && eFound == false) {
number[j++] = s[i];
}
i++
}
I tried to do this:
i = 0;
while (isdigit(number[i])){
i++;
}
printf("%d", i);
number[i] = 'b';
I have no compile errors, but when running program visual studio says
"Debug Assertion Fail".
Why is this not possible to do in C?
EDIT (whole code added):
#pragma warning(disable:4996) //disables crt warnings
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include<string.h>
double stof(char s[]);
int main(){
char string[] = "123.45e-10";
stof(string);
}
double stof(char s[]) {
bool isNegative = false;
bool eFound = false;
int i = 0;
int j = 0;
int k = 0;
char number[10];
char potention[11];
int dotPosition;
while (s[i] != '\0') {
if (isdigit(s[i]) && eFound == false) {
number[j++] = s[i];
}
else if (s[i] == '.') {
dotPosition = i;
}
else if (s[i] == 'e' || s[i] == 'E')
eFound = true;
else if (s[i] == '-')
isNegative = true;
else if (eFound== true && isdigit(s[i])){
potention[k++] = s[i];
}
i++;
}
i = 0;
while (isdigit(number[i])){
i++;
}
printf("%d", i);
number[i] = 'b';
const int charSize = dotPosition;
int potentionN = atoi(potention);
char beforeDecimal[sizeof(number)];
char addedNulls[20];
int g = 0;
if (isNegative == true) {
strncpy(beforeDecimal, number, dotPosition);
int addNull = potentionN - sizeof(beforeDecimal);
printf("%d", addNull);
while (g < addNull) {
addedNulls[g] = '0';
g++;
}
printf("%d", strlen(addedNulls));
}
return 0.0;
}
Why is this not possible to do in C?
Every computable answer can be found with a Turing-complete language. Your question is more like, where is the error in my code?
In C, it's very important to ensure you read & write only to defined memory: those locations covered by your variables. You're testing your input locations with
while (s[i] != '\0')
but nowhere do you ensure that you stay within the bounds of number and potention. Especially here:
i = 0;
while (isdigit(number[i])){
i++;
}
At no point do you write a nondigit to number. Why should that loop ever end?
The instant fix is to initialize number:
char number[10] = {};
That causes the compiler to initialize the array with any elements inside {}, and the rest of it with zeros. Since the initializer is empty, the whole array is filled with zeros.
That way, provided you don't fill number with digits, your while loop will terterminate. A belt-and-suspenders solution is make double-sure:
i = 0;
while (i < sizeof(number) && isdigit(number[i])) {
i++;
}
I haven't debugged your whole program; I haven't even compiled it. The run-time error you're seeing suggests you're writing to undefined memory. If you check the array bounds in each loop, you can avoid that particular problem and move on to the next one. ;-)
I'm doing my C programming course homework and I need to find a most common character in given file.
My testing with a testfile, emptyfile and other small amount text files works great (or at least I think so), but in the last long testfile something goes wrong and the error message is: "Should have returned 'e' (101) for file rfc791.txt. You returned 'b' (98)".
So what I'm asking that what might be wrong with my code, when suddenly the most common letter is not what is should be?
int most_common_character(char *filename) {
FILE *f;
if ((f = fopen(filename, "r")) == NULL) {
fprintf(stderr, "Not opened: %s\n", strerror(errno));
return -1;
}
char frequency[26];
int ch = fgetc(f);
if (ch == EOF) {
return 0;
}
for (ch = 0; ch < 26; ch++) {
frequency[ch] = 0;
}
while (1) {
ch = fgetc(f);
if (ch == EOF) {
break;
}
if ('a' <= ch && ch <= 'z') {
frequency[ch - 'a']++;
}
else if ('A' <= ch && ch <= 'Z') {
frequency[ch - 'A']++;
}
}
int maxCount = 0;
int maxChar = 0;
for (int i = 0; i <= 26; ++i) {
if (frequency[i] > maxCount) {
maxCount = frequency[i];
maxChar = i;
}
}
fclose(f);
return maxChar + 'a';
}
I would be very grateful if someone has any hints to fix my code :) I've tried to search the solution to this problem from many other related topics but nothing seems to work.
You should use < operator in the second for loop. Because of that when you are checking frequency[i] > maxCount, at frequency[26] it behaves undefined behaviour, meaning the value at that index may be less or higher than the compared value.
Your code do have some problems. However, they are so tiny so the code still works well with small tests.
int ch = fgetc(f); drop the first char in the file
for (int i = 0; i <= 26; ++i) break out of the array 's range (only from 0-->25)
Beside these small mistakes, your code is awesomely fine. Well done #thumbsup
Loop runs out-of-bounds. #Weather Vane
// for (int i = 0; i <= 26; ++i) {
for (int i = 0; i < 26; ++i) {
Code throws away result of the first character. #BLUEPIXY
int ch = fgetc(f);
if (ch == EOF) {
return 0;
}
// This value of ch is not subsequently used.
Other fixes as below
int most_common_character(char *filename) {
...
// Use a more generous count #Weather Vane
// char frequency[26];
// Consider there may be more than 26 different letters
// fgetc return EOF and value in the unsigned char range
int frequency[UCHAR_MAX + 1] = { 0 };
// Not needed as array was initialize above
// for (ch = 0; ch < 26; ch++) { frequency[ch] = 0; }
// BTW correct type declaration of int, avoided rookie mistake of using char
int ch;
// Codes use tolower(), islower() as that is the portable way to
// handle type-of-character detection
while ((ch = fgetc(f)) != EOF) {
frequency[tolower(ch)]++; // could add check to insure frequency[] does not overflow
}
int maxCount = 0;
int maxChar = -1;
for (int i = 0; i <= UCHAR_MAX; ++i) {
if (islower(i) && frequency[i] > maxCount) {
maxCount = frequency[i];
maxChar = i;
}
}
fclose(f);
return maxChar;
}
My code should find hex numbers in a user input (followed or not by 0x), copy them in an array as a string and, every time it finds a non 1-9 a-f A-F character or EOF, it should execute the htoi function converting the characters in the string into a decimal number, proceeding from right to left and using a multiplier to account for the position. It doesn't do what it's supposed to do. It generates numbers that have nothing to do with the decimal equivalent of my hex numbers.
#include <stdio.h>
#include <string.h>
#include <math.h>
int htoi(char num[]);
int main()
{
int c,i = 0;
char num[1000];
while ((c = getchar()) != EOF)
{
if ((c > '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'a' && c <= 'f'))
{
num[i] = c;
i++;
}
else if (c == '0')
{
if ((c = getchar) == 'x' || c == 'X')
{
num[i] = '\0';
printf("%d", htoi(num));
i=0;
}
else
{
num[i] = c;
i++;
}
}
else
{
num[i] = '\0';
if (num[0] != '\0')
{
printf("%d", htoi(num));
}
i=0;
}
}
num[i] = '\0';
if (num[0] != '\0')
{
printf("%d", htoi(num));
}
i=0;
return 0;
}
int htoi(char num[])
{
int c,i, dig;
int dec;
int multiplier = 1;
for (i = strlen(num)-1; i >= 0; i--)
{
c = num[i];
if (c > '0' && c <= '9')
{
dig = c - '0';
}
else if (c > 'a' && c <= 'f')
{
dig = c - 'a' + 10;
}
else if (c > 'A' && c <= 'F')
{
dig = c - 'A' + 10;
}
dec = dec + dig * multiplier;
multiplier * 16;
return dec;
}
}
Three problems:
multiplier * 16; just throws away the result. You'd want multiplier *= 16
return dec returns immediately with the current value of dec. You should have that after the loop.
The variable dec is uninitialized, which means it will have an indeterminate value. Using it without initialization, like you do, will lead to undefined behavior.
There are other problems as well, some of which would have been caught by the compiler leading to errors or warnings. The three above was just what I found after a quick glance.
I'm trying to do a space with line replacer for Ti-89 calculators so that I can print lines without them being cut because of the horizontal character length. They would normally look like so
This is a pretty long test
ing for the Ti89 Calculator
and I would like them to look like so
This is a pretty long
testing for the Ti89
Calculator
I tried to do it with this code
void _print_line(char* string)
{
int k = strlen(string);
if(k > 26)
{
int n = 0;
int c = 25;
while(n == 0)
{
if(string[c] == 32)
{
n = 1;
}
else
{
c--;
}
if(c <= 0)
{
n = 2;
}
}
if(n == 1)
{
string[c] == '\n';
}
}
printf("%s\n", string);
}
But it seems to just ignore it and keep printing it like the first example.
You are not inserting the carriage return.
Replace
string[c] == '\n';
With
string[c] = '\n';
As Till said, you are not inserting the carriage return. The line
string[c] == '\n';
needs to be
string[c] = '\n';
With the difference being one "equals" sign versus two.
The reason is because "==" is a conditional operator which evaluates to either true or false, while "=" is the assignment operator which sets a value to a variable.
There needs to be processed for the entire string.
Keep a record of the current output character position to check whether or not exceed the specified width when you output the next word.
like this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define DISP_OUT stdout
#define DISP_WIDTH 26
int disp_one(char ch){
static int pos;
fputc(ch, DISP_OUT);
if(ch == '\n')
pos = 0;
else
++pos;
if(pos == DISP_WIDTH){
fputc('\n', DISP_OUT);
pos = 0;
}
return pos;
}
typedef enum word_break {
KEEP, BREAK
} WORD_BREAK;
void disp(const char *str, WORD_BREAK word_break){
static int pos;
switch(word_break){
case BREAK:
while(*str){
pos = disp_one(*str++);
}
break;
case KEEP:
while(*str){
if(isspace((unsigned char)*str)){
pos = disp_one(*str++);
continue;
}
const char *end = str;//end : word end (find delimiter)
while(*end && !isspace((unsigned char)*end))
++end;
int len = end - str;//length of next output word
if(pos + len >= DISP_WIDTH && len < DISP_WIDTH){
pos = disp_one('\n');
}
while(str < end){
pos = disp_one(*str++);
}
}
break;
}
}
int main(void){
char *text = "This is a pretty long testing for the Ti89 Calculator";
disp(text, BREAK);
disp("\n", BREAK);
disp(text, KEEP);
return 0;
}
I am trying to implement the rot13-algorithm in C.
But since I am not very familiar with that language, I have some problems with my code right here.
Basically, I want to rotate every letter in args[] to 13 positions up.
But this code seems to be pretty sluggish:
#include <stdio.h>
char[] rotate(char c[]) {
char single;
int i;
int alen = sizeof(c)/sizeof(c[0]);
char out[alen];
for(i=0;i<=alen;i+=1) {
if(c[i]>='a' && (c[i]+13)<='z'){
out[i] = c[i]+13;
}
}
return out;
}
int main(int argc, char *argv[]) {
printf("The given args will be rotated\n");
int i;
char rotated[sizeof(argv)/sizeof(argv[0])];
rotated = rotate(argv);
/* printing rotated[] later on */
return 0;
}
I know there a lot of holes here - could you show me how to fix this?
Thanks a lot guys, I solved the problem with this code
#include <stdio.h>
int rot13(int c){
if('a' <= c && c <= 'z'){
return rot13b(c,'a');
} else if ('A' <= c && c <= 'Z') {
return rot13b(c, 'A');
} else {
return c;
}
}
int rot13b(int c, int basis){
c = (((c-basis)+13)%26)+basis;
return c;
}
int main() {
printf("The given args will be rotated");
int c;
while((c = getchar()) != EOF){
c = rot13(c);
putchar(c);
}
return 0;
}
How #Michael said this char out[alen] is not accepted by the compiler because you can't declare an array size with a non constant value. Another problem of your code is the for loop for( i = 0; i < = alen; i+=1 ) the arrays start on 0 so if you do the for until the lenght's position you will be out of the array.
About the code:
You must use a pointer to the start of the string as argument of the function, because You can't return arrays in C (But you can return pointers ).
Your if( str[i] >= 'a' && (str[i]+13) <='z') is incorrect because you will convert some letters into symbols take a look.
________
--------------------------!
void rotate( char * str )
{
int i = 0;
/* You do this until you find a '\0' */
for( i = 0; str[ i ] != '\0' ; i++ ){
/* Use the pointer notation if you passed a pointer. */
/* If the letter is between a and m you can simply sum it. */
if( *( str + i ) >= 'a' && *( str + i ) < 'n')
*( str + i ) += 13;
/* If the letter is between the n and z you have to do the opposite.*/
else if( *( str + i ) >= 'n' && *( str + i ) <= 'z')
*( str + i ) -= 13;
}
}
Size of arrays in C must be set at compile time, so you can't use non constant expression for array size.
Consider the below implementation:
// in place rotate
void rotate(char *str)
// str must be a zero-terminated string
{
int i =0;
// loop until str itself is not NULL and str[i] is not zero
for(i=0;str && str[i]; ++i) // ++i is a pre-increment
{
if(str[i] >= 'a' && (str[i]+13) <='z')
{
str[i] = str[i]+13; // modifying str in place
}
}
}
Then your main() can look like this:
int main(int argc, char *argv[])
{
printf("The given args will be rotated: %s\n", argv[1]);
rotate(argv[1]);
printf("Rotated: %s\n", argv[1]);
return 0;
}
Update More advanced version of the transform that takes care of case when str[i] + 13 > 'z'
for(i=0;str && str[i]; ++i) // ++i is a pre-increment
{
// ignore out of range chars
if (str[i] < 'a' || str[i] > 'z') continue;
// rotate
for (off = 13; off > ('z' - str[i]); )
{
off-= (1 + 'z' - str[i]);
str[i] = 'a';
}
str[i]+=off;
}
This function can encode/decode to/from rot13 string. It's compatible with VIM's g? rot13 encoder.
void rot13 (char *s) {
if (s == NULL)
return;
int i;
for (i = 0; s[i]; i++) {
if (s[i] >= 'a' && s[i] <= 'm') { s[i] += 13; continue; }
if (s[i] >= 'A' && s[i] <= 'M') { s[i] += 13; continue; }
if (s[i] >= 'n' && s[i] <= 'z') { s[i] -= 13; continue; }
if (s[i] >= 'N' && s[i] <= 'Z') { s[i] -= 13; continue; }
}
}