I wrote a rot13.c program but I can tell something in my loop inside rot13_translate_string is causing the program to just print out blank lines.
Any thoughts?
Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char rot13_translate_character(char c)
{
if( 'A' <= c && c <= 'M' )
{
return c + 13;
}
else if( 'N' <= c && c <= 'Z' )
{
return c - 13;
}
else if( 'a' <= c && c <= 'm' )
{
return c + 13;
}
else if( 'n' <= c && c <= 'z' )
{
return c - 13;
}
else
{
return c;
}
}
char *rot13_translate_string(const char *str)
{
int len = strlen(str);
char *translation = calloc(len, sizeof(char));
int i;
do //****HERE IN THIS SECTION
{
/* Translate each character, starting from the end of the string. */
translation[len] = rot13_translate_character(str[len]);
len--;
} while( len < 0 ); //<
return translation;
}
And here is the main (part of the same file) - is the condition for my for i = 1 ok?
int main(int argc, char **argv)
{
if( argc < 2)
{
fprintf(stderr, "Usage: %s word [word ...]\n", argv[0]);
return 1;
}
/* Translate each of the arguments */
int i;
for( i = 1; i < argc; i++) //*****IS this right?
{
char *translation = rot13_translate_string( argv[i] );
fprintf(stdout, "%s\n", translation);
}
return 0;
}
As just it was pointed out by Janis is the control on the loop do ... while. It should be
while( len >= 0 );
A "while" loop runs while the control expression is true (and terminates once the expression becomes false). You define the variable len just before the loop and it cannot be <0.
So you never really enter in the loop.
You obtain a line for each input word because of fprintf(stdout, "%s\n", translation); line, where you print for each (empty) word a line (\n).
In other languages, for example in Pascal, there is "repeat until" loop construction, which continues to run until the control expression is true, and only after that it changes it terminates.
In that case you could use a condition with <0.
In C to follow the same logic you can use while loop and negate the condition. In your case
} while (! (len < 0) );
Related
I need to make a c program that will make a histogram of all the letters present in a phrase the user gives. When I run it, I does it but gives a "* stack smashing detected *: terminated". Where would this error be coming from? (for ease right now I set max to 3). In the future i'll have it find the max
Thank you
Andrew
#include <stdio.h>
#include <ctype.h>
#include <string.h>
static void ReadText(int histo[26],int max) {
char phrase[100];
int i;
char Letter;
char toArray;
// read in phrase
printf("Enter Phrase: "); // reads in phrase with spaces between words
scanf("%[^\n]",phrase);
// count the number of certain letters that occur
for(i = 0; i <= strlen(phrase);++i) {
Letter = phrase[i];
if(isalpha(Letter) != 0){
Letter = tolower(Letter);
toArray = Letter - 97;
histo[(int)toArray] = histo[(int)toArray] + 1;
}
}
}
static void DrawHist(int histo[26], int max){
int i;
int j;
int histo2[50];
for(i = 0; i <= 26; i++) {
histo2[i+i] = histo[i];
if(i < 25) {
histo2[i+i+1] = 0;
}
}
// (i = 1; i <= 50; i++) {
// printf("%d",histo2[i]);
//}
//printf("\n");
for(i=max;i>0;--i) {
for(j=0;j<=51;++j) {
if((j < 51) && (histo2[j] >= i)) {
printf("|");
}
else if((j < 51) && (histo2[j] < i)){
printf(" ");
}
else if(j == 51){
printf("\n");
}
}
}
printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
printf("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z\n");
}
int main() {
int histo[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int max = 3;
//int i;
ReadText(histo,max);
//for(i = 0; i<26;++i) {
// printf("%d",histo[i]);
//}
DrawHist(histo,max);
return 0;
}
Could anyone please help me understand why Clang reallocates the same memory address for different variables while their lifetimes intersect?
I am using a sample program (below) to show the problem.
When I compile the program with clang -O0, variable j in function ok has the same memory address as variable solutions in function nqueens.
Function ok is called inside function nqueens, which means that the lifetime of the variables intersect; the same stack space cannot be used/reused for both functions.
Compiling the program with gcc or clang at -O1, however, they are assigned different memory addresses.
Any help is appreciated!
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <alloca.h>
/* Checking information */
static int solutions[] = {
1,
0,
0,
2,
10, /* 5 */
4,
40,
92,
352,
724, /* 10 */
2680,
14200,
73712,
365596,
};
#define MAX_SOLUTIONS sizeof(solutions)/sizeof(int)
int total_count;
int sharedVar = 0;
int ok(int n, char *a)
{
int i, j;
char p, q;
printf("jjjjjjjjj: %d, %p\n", n,&j);
for (i = 0; i < n; i++) {
p = a[i];
for (j = i + 1; j < n; j++) {
q = a[j];
if (q == p || q == p - (j - i) || q == p + (j - i))
return 0;
}
}
return 1;
}
void nqueens (int n, int j, char *a, int *solutions)
{
int i,res;
sharedVar = sharedVar * j - n;
if (n == j) {
/* good solution, count it */
*solutions = 1;
return;
}
printf("solutions: %d, %p\n", j, &solutions);
*solutions = 0;
/* try each possible position for queen <j> */
for (i = 0; i < n; i++) {
a[j] = (char) i;
if (ok(j + 1, a)) {
nqueens(n, j + 1, a,&res);
*solutions += res;
}
}
}
int main()
{
int size = 3;
char *a;
// printf("total_count: %p\n", &total_count);
total_count=0;
a = (char *)alloca(size * sizeof(char));
printf("Computing N-Queens algorithm (n=%d) ", size);
sharedVar = -5;
nqueens(size, 0, a, &total_count);
printf("completed!\n");
printf("sharedVar: %d\n", sharedVar);
}
I want to make the printf function print from right to left because this program convert the value of number to binary and I want it to be printed in proper form for example if I convert 16 it is written like that 00001 but it must look like that 10000 so does anyone know how to do that thanks in advance
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x,rem;
printf("please enter number: ");
scanf("%d",&x);
while (x !=0)
{
rem=x%2;
if (rem==0)
{
printf("0");
}
else
{
printf("1");
}
x = x/2;
rem = 0;
}
return 0;
}
Here it is:
void print_binary(int x)
{
int skip = 1;
unsigned int mask = 1 << 31;
while(mask > 0){
if(x & mask){
skip = 0;
printf("1");
}else{
if(!skip) printf("0");
}
mask >>= 1;
}
printf("\n");
}
This will print the binary number without trailing zeroes.
If you rather want the result to be stored in a string, you can use:
#include <string.h>
void int_to_binary(int x, char * buff) // buff size must be >= 32 !
{
buff[0] = '\0'; // ensure string ends with \0
unsigned int mask = 1 << 31;
for (; mask > 0; mask >>= 1)
{
strcat(buff, (x & mask) ? "1" : "0");
}
}
To check both codes, use:
int main(int argc, char* argv[])
{
int x;
printf("please enter number: ");
scanf("%d",&x);
char bin[32];
int_to_binary(x, bin);
printf("%s\n", bin);
print_binary(x);
}
What we do is using a mask, which in binary is one "1" beginning on the far left and moving one step right at each loop. The "&" is a bite-wise operator (I let you google it to know how it works). If you need more explanation, feel free to ask.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int binary[20];
int q,i=0;
printf("Enter the decimal no\n");
scanf("%d",&q);
while(q > 0)
{
binary[i]=q%2;
i++;
q=q/2;
}
for(int j=i-1;j>=0;j--)
{
printf("%d",binary[j]);
}
return 0;
}
Alright, i have a hw assignment to check if an inserted string is a palindrome. The string must first be inserted into a stack, a queue, and then compared. I have the program up and running, for me that is. My teacher, when trying to grade it experience(d) a run time error. Also, getline portable is a requirement of the assignment and came with the file and instructions.
This is the note from the teacher:
Check if a line is a palindrome. Ignore spaces? y/n y (her running the code)
Input line to check
(where she gets the runtime error)
175 [main] csc240Summer2014PE8Student 10060 open_stackdumpfile: Dumping stack trace to csc240Summer2014PE8Student.exe.stackdump
#include <iostream>
#include <stack>
#include <queue>
#include <string>
using namespace std;
istream& getline_portable( istream& is, string& str ) {
istream& ris = std::getline(is,str);
if ( str.size() && str[str.size()-1] == '\r' )
str.resize(str.size()-1);
return ris;
}
int main()
{
stack<char> s;
queue<char> q;
char c, choice, b;
string str;
int i = 0;
int count = 0;
do
{
cout<<"Check if a line is a palindrome. Ignore spaces? y/n ";
cin >> b;
cin.ignore();
tolower(b);
cout<<"Input line to check\n";
getline_portable(cin,str);
for(int j = 0; j < str.size(); j++)
str[j] = tolower(str[j]);
if(b == 'n')
{
for(int j = 0; j < str.size(); j++)
{
c = str[j];
q.push(c);
s.push(c);
}
}
else if (b == 'y')
{
for(int j = 0; j < str.size() - count; j++)
{
c = str[j];
if(isspace(c))
{
}
else if(!isspace(c))
{
q.push(c);
s.push(c);
}
}
}
do
{
if(q.front() != s.top())
{
i = false;
break;
}
else
{
i = true;
s.pop();
q.pop();
}
}while(!q.empty() && !s.empty());
if (i == true)
cout << str << " is a pallindrom.\n";
else if (i == false)
cout << "Your input of " << str << " is not a pallindrome.\n";
cout << "Would you like to test another string? y/n ";
cin >> choice;
tolower(choice);
cin.ignore();
}while (choice == 'y');
cout << "Press enter to continue...";
cin.get();
return 0;
}
My program is supposed to fork three processes. Each of these processes will create three threads and fork two additional processes. These two additional processes will create three threads.
Here is my code. I've tried to keep things simple with nested loops. I think at some point I might be forking more processes or creating more threads.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *printme(void* Array){
int *Arr = (int *) Array;
int len = sizeof(Arr) / sizeof(int);
if (len == 1){
printf("I'm thread %d.%d",Arr[0],Arr[1]);
}
else if (len == 2){
printf("I'm thread %d.%d.%d",Arr[0],Arr[1],Arr[2]);
}
printf("\n");
pthread_exit(NULL);
}
int main(void){
int i, j, k, l;
int threadLevel1[2];
int threadLevel2[3];
printf("\n");
for (i = 1 ; i < 4 ; i++){ // Loop to fork the three main processes.
if (fork() != 0){
sleep(4);
}
else{
//The newly forked process will create three threads and fork two additional processes.
for (j = 1 ; j < 4 ; j++){
pthread_t t;
threadLevel1[0] = i;
threadLevel1[1] = j;
if (pthread_create(&t, NULL, printme, (void*) threadLevel1) != 0){
perror("pthread_create");
exit(1);
}
}
for (k = 1; k < 3 ; k++){
pid_t a = fork();
if (a != 0){
sleep(2);
}
else if (a == -1){
perror("fork"); /* display error message */
exit(0);
}
else{
for (l = 1 ; l < 4 ; l++){
pthread_t t;
threadLevel2[0] = i;
threadLevel2[1] = k;
threadLevel2[2] = l;
if (pthread_create(&t, NULL, printme, (void*) threadLevel2)!=0) {
perror("pthread_create");
exit(1);
}
}
}
}
}
}
return 0;
}
You have a problem in your code here:
void *printme(void* Array){
int *Arr = (int *) Array;
int len = sizeof(Arr) / sizeof(int);
The value len will always be the same no matter what is passed in to printme. That's because C passes arrays as pointers, not as objects with embedded lengths.