• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

PmtacTL.jpg


i just started learning about multidimensional arrays in C++

i have a couple more sets of questions like this and i have no idea to figure out what the outputs are, ive been pulling my hair out the past hour and a half trying to figure it out ><

id love it if someone could explain how these answers were gotten so i can make sense of the rest of the problems
 
It keeps repeating "The square number is" ? You're outputting i so what is i looking like when it repeats?

Yeah it is repeating that . I am trying to get 1 the square is 1, 3 is 9, and so on.
It keeps repeating i and pow(i, 2), by constantly increasing and not stopping to 10.

If I change it around it just repeats a number.
 

mercviper

Member
Yeah it is repeating that . I am trying to get 1 the square is 1, 3 is 9, and so on.
It keeps repeating i and pow(i, 2), buy constantly increasing and not stopping to 10.

If I change it around it just repeats a number.

Well the current setup says the loop runs when less than or equal to 1 or greater than or equal to 10. So if it ever gets to 10 it'll just keep going since you add 1 in the loop.

Then again, you start at 1 right before the loop so it shouldn't run more than once anyway because you hit i==2.

Try removing the extra () around the conditionals? I think it doesn't matter but it won't hurt to check.
 
PmtacTL.jpg


i just started learning about multidimensional arrays in C++

i have a couple more sets of questions like this and i have no idea to figure out what the outputs are, ive been pulling my hair out the past hour and a half trying to figure it out ><

id love it if someone could explain how these answers were gotten so i can make sense of the rest of the problems

Think of x as being a matrix x[1][1] is the value at row 1, column 1 (and remember that c is a 0 based indexing language).

In other words is a structure that looks like:

1,2,3
4,5,6

So x[0][0] is 1, x[0][1] is 2 and so on.
 
Think of x as being a matrix x[1][1] is the value at row 1, column 1 (and remember that c is a 0 based indexing language).

In other words is a structure that looks like:

1,2,3
4,5,6

So x[0][0] is 1, x[0][1] is 2 and so on.
That makes sense.. But the rest look super hard

Can you explain b and c please?

I just want it to start making some sense so I can understand the mechanics of it

I wish it were explained in the book or at least explained in class, I tried YouTube and google but nothing -__-
 
That makes sense.. But the rest look super hard

Can you explain b and c please?

I just want it to start making some sense so I can understand the mechanics of it

I wish it were explained in the book or at least explained in class, I tried YouTube and google but nothing -__-

I think it's just asking what numbers the array will spit out given a certain action being taken. That being said, take my answers with a cup of salt since I have about 2 weeks worth of coding experience, but lots of school experience.

At line B, the For loop will run from i = 0 to i = 1 but then quit before i = 2. At the point where i = 0, the "cout" (I'm assuming this is just a printf?) will spit out x[0][0]. which equals 1 in your matrix array. When i = 1, cout will spit out x[1][1] which equals 4 in your array, and then the for loop will quit.

Line C is just using substitution. x[x[0][0]] x[0][1]] can be split up into the outer array x[ -inside stuff- ] and the inside stuff is x[0][0] and x[0][1]. x[0]0] = 1 and x[0][1] = 2 so the outer array equals x[1][2] which equates to 5 in your matrix. Not sure if that helps.

My school puts all of our lectures, sections, and study material online and Slide 6 and 7 on this page here go over multidimensional arrays and at the bottom of the page there are videos going over arrays from lecture and a short video done by one of the TAs. There might be more in our lectures, so I'll take a look and see if I can find something that can better illustrate it. Note that the page in relation to C and not C++, but the general ideas transfer pretty easily since C++ is an extension.

Thanks so much!!!

I'm just glad I made sense. English is my second language, so I don't usually do well explaining things like this. Plus, I'm pretty new to coding in general.
 
Well b is a a for loop, have you covered loops yet?

https://en.wikipedia.org/wiki/For_loop

C kind of goofy. Its taking the values at certain spots in the array and then using them to index into the array. Try unraveling it one step at a time:

x[x[0][0]][x[0][1]]]
First figure out what x[0][0] is, and then figure out what x[0][1] is. Then use those values to get the final values.

Read this as well: http://www.cplusplus.com/doc/tutorial/arrays/ for some more help.
 
I think it's just asking what numbers the array will spit out given a certain action being taken. That being said, take my answers with a cup of salt since I have about 2 weeks worth of coding experience, but lots of school experience.

At line B, the For loop will run from i = 0 to i = 1 but then quit before i = 2. At the point where i = 0, the "cout" (I'm assuming this is just a printf?) will spit out x[0][0]. which equals 1 in your matrix array. When i = 1, cout will spit out x[1][1] which equals 4 in your array, and then the for loop will quit.

Line C is just using substitution. x[x[0][0]] x[0][1]] can be split up into the outer array x[ -inside stuff- ] and the inside stuff is x[0][0] and x[0][1]. x[0]0] = 1 and x[0][1] = 2 so the outer array equals x[1][2] which equates to 5 in your matrix. Not sure if that helps.

My school puts all of our lectures, sections, and study material online and Slide 6 and 7 on this page here go over multidimensional arrays and at the bottom of the page there are videos going over arrays from lecture and a short video done by one of the TAs. There might be more in our lectures, so I'll take a look and see if I can find something that can better illustrate it. Note that the page in relation to C and not C++, but the general ideas transfer pretty easily since C++ is an extension.
Thanks so much!!!

Purple Cheeto: I've done for loops but I should review it because it's still a bit strange to me still

An outer for loop handles rows and a nested one suddenly handles columns, that always makes me wonder why it works like that and I need to tie that to the line b question still and figure out what's going on

Thank you for the links I'll check them out :)
 
I'm about to go to bed so won't be able to reply to any responses until I wake up, but this has been frustrating me for a bit and I don't know what I have done wrond and my C++ debugging skills are still quite poor.

I'm going to comment this code more properly tomorrow as well.

Essentially, we have to make a basic ray-tracer that runs on the CPU as an assignment. We've been told to do it in Java, but I asked if I could do it in C++ instead as I want to learn C++ and got told yes, so I decided to whack the following code together tonight (using Handmade Hero's framebuffer which Casey very kindly let my use). All the relevant stuff is in https://github.com/Moosichu/RayTracer/blob/master/src/ray_tracer.cpp.

However, when I run my program, nothing is being drawn to the screen :(, and I can't work out why.

The reason I think the error is here, is because if I set the ambientFactor color to a value, the entire screen will be filled with that. It's just that no circles are being drawn which is what I want essentially as I have just implement the ambient component of spheres.
Code:
Color traceRay(Ray ray,
               Sphere sceneObjects[], std::size_t numObjects,
               PointLight lights[], std::size_t numLights,
               int recurseDepth) {
    LightCollision closestCollision;
    closestCollision.position = {600000.0, 60000.0, 60000.0}; //TODO(Tom) Replace with max possible scalar values
    closestCollision.normal = {1.0, 0, 0};
    closestCollision.ambientFactor = {0, 0, 0};
    closestCollision.diffuseFactor = {0, 0, 0};
    closestCollision.specularFactor = {0, 0, 0};

    //Find the closest position
    for(std::size_t i = 0; i < numObjects; i++) {
        //TODO(Tom) Have a way of handling type of sceneObject
        {
            Sphere sphere = sceneObjects[i];

            Vector3D sphereToRayOrigin = sphere.position - ray.origin;
            scalar a = ray.direction.dot(ray.direction); //a = |ray.direction|^2
            scalar b = 2 * ray.direction.dot(sphereToRayOrigin);
            scalar c = sphereToRayOrigin.dot(sphereToRayOrigin) - (sphere.radius*sphere.radius);
            scalar d;
            {
                double intermediate = (b*b) - (4*a*c);
                if(intermediate < 0) {
                    continue; //No intersection
                }
                d = sqrt(intermediate);
            }

            double s1 = (-b + d)/(2*a);
            double s2 = (-b - d)/(2*a);
            double s = s1 < s2 ? s1 : s2; //select the closest point intersection
            if(s < 0) {
                continue;
            }
            
            //Work out the position of the collision relateve to the camera's location
            Vector3D collisionOffset = ray.direction * s;
            if(collisionOffset.square() < closestCollision.position.square()) { //Comparing magnitudes
                closestCollision.position = collisionOffset;
                //TODO(Tom) Calculate the normal of the collision!
                closestCollision.ambientFactor = sphere.ambientFactor;
                closestCollision.diffuseFactor = sphere.diffuseFactor;
                closestCollision.specularFactor = sphere.specularFactor;
            }
        }
    }

    
    Color finalColor = closestCollision.ambientFactor;
    if(recurseDepth > 0) {
        Color diffuseComponent;
        Color specularComponent;

        //check to make sure any diffuse components actually have to be calculated
        if (closestCollision.diffuseFactor.red |
            closestCollision.diffuseFactor.green |
            closestCollision.diffuseFactor.blue) {
            //TODO(Tom) recursively calculate diffuse components and add to final color variable
            
        }

        //check to make sure any specular components actually have to be calculated
        if (closestCollision.specularFactor.red |
            closestCollision.specularFactor.green |
            closestCollision.specularFactor.blue) {
            //TODO(Tom) recursively calculate specular component and add to final color variable
        } 
    }
        
    return finalColor;
}

Sorry about this huge code dump, I'm very tired and something glaringly obvious will probably jump out in the morning, but I also have a huge fear that I will spend hours trying to track down a niggly bug.
I'm guessing the error is somewhere in my collision detection section, but I did already implement this in java and it worked fine and I have just been porting my work there to C++ so there shouldn't be any issues with the basic maths.

If this code is more or less equivalent Java code, you might have to think about passing things by reference OR defining all the Copy constructors. Your finalColor variable is allocated on the stack, so that could definitely cause some issues.

You really need to think of C++ as a very different beast then Java. Might want to check out Stack vs Heap allocation and pass-by-value vs pass-by-reference.
Don't worry, though, I've made the same mistakes a million times, when starting C++ and coming from a higher level language. You could probably buy a book or something and that could really help.
 

Moosichu

Member
If this code is more or less equivalent Java code, you might have to think about passing things by reference OR defining all the Copy constructors. Your finalColor variable is allocated on the stack, so that could definitely cause some issues.

You really need to think of C++ as a very different beast then Java. Might want to check out Stack vs Heap allocation and pass-by-value vs pass-by-reference.
Don't worry, though, I've made the same mistakes a million times, when starting C++ and coming from a higher level language. You could probably buy a book or something and that could really help.

At the moment I'm putting everything on the stack and not using pointers at all so everything should be fine. The Color struct is simply a way of wrapping 4 bytes into a single data structure. I have a book and as far as I'm aware, the value of the finalColor variable is copied on return into the code that is calling it. Or am I wrong?
 
I'm about to go to bed so won't be able to reply to any responses until I wake up, but this has been frustrating me for a bit and I don't know what I have done wrond and my C++ debugging skills are still quite poor.

I'm going to comment this code more properly tomorrow as well.

Essentially, we have to make a basic ray-tracer that runs on the CPU as an assignment. We've been told to do it in Java, but I asked if I could do it in C++ instead as I want to learn C++ and got told yes, so I decided to whack the following code together tonight (using Handmade Hero's framebuffer which Casey very kindly let my use). All the relevant stuff is in https://github.com/Moosichu/RayTracer/blob/master/src/ray_tracer.cpp.

However, when I run my program, nothing is being drawn to the screen :(, and I can't work out why.

The reason I think the error is here, is because if I set the ambientFactor color to a value, the entire screen will be filled with that. It's just that no circles are being drawn which is what I want essentially as I have just implement the ambient component of spheres.
Code:
Color traceRay(Ray ray,
               Sphere sceneObjects[], std::size_t numObjects,
               PointLight lights[], std::size_t numLights,
               int recurseDepth) {
    LightCollision closestCollision;
    closestCollision.position = {600000.0, 60000.0, 60000.0}; //TODO(Tom) Replace with max possible scalar values
    closestCollision.normal = {1.0, 0, 0};
    closestCollision.ambientFactor = {0, 0, 0};
    closestCollision.diffuseFactor = {0, 0, 0};
    closestCollision.specularFactor = {0, 0, 0};

    //Find the closest position
    for(std::size_t i = 0; i < numObjects; i++) {
        //TODO(Tom) Have a way of handling type of sceneObject
        {
            Sphere sphere = sceneObjects[i];

            Vector3D sphereToRayOrigin = sphere.position - ray.origin;
            scalar a = ray.direction.dot(ray.direction); //a = |ray.direction|^2
            scalar b = 2 * ray.direction.dot(sphereToRayOrigin);
            scalar c = sphereToRayOrigin.dot(sphereToRayOrigin) - (sphere.radius*sphere.radius);
            scalar d;
            {
                double intermediate = (b*b) - (4*a*c);
                if(intermediate < 0) {
                    continue; //No intersection
                }
                d = sqrt(intermediate);
            }

            double s1 = (-b + d)/(2*a);
            double s2 = (-b - d)/(2*a);
            double s = s1 < s2 ? s1 : s2; //select the closest point intersection
            if(s < 0) {
                continue;
            }
            
            //Work out the position of the collision relateve to the camera's location
            Vector3D collisionOffset = ray.direction * s;
            if(collisionOffset.square() < closestCollision.position.square()) { //Comparing magnitudes
                closestCollision.position = collisionOffset;
                //TODO(Tom) Calculate the normal of the collision!
                closestCollision.ambientFactor = sphere.ambientFactor;
                closestCollision.diffuseFactor = sphere.diffuseFactor;
                closestCollision.specularFactor = sphere.specularFactor;
            }
        }
    }

    
    Color finalColor = closestCollision.ambientFactor;
    if(recurseDepth > 0) {
        Color diffuseComponent;
        Color specularComponent;

        //check to make sure any diffuse components actually have to be calculated
        if (closestCollision.diffuseFactor.red |
            closestCollision.diffuseFactor.green |
            closestCollision.diffuseFactor.blue) {
            //TODO(Tom) recursively calculate diffuse components and add to final color variable
            
        }

        //check to make sure any specular components actually have to be calculated
        if (closestCollision.specularFactor.red |
            closestCollision.specularFactor.green |
            closestCollision.specularFactor.blue) {
            //TODO(Tom) recursively calculate specular component and add to final color variable
        } 
    }
        
    return finalColor;
}

Sorry about this huge code dump, I'm very tired and something glaringly obvious will probably jump out in the morning, but I also have a huge fear that I will spend hours trying to track down a niggly bug.
I'm guessing the error is somewhere in my collision detection section, but I did already implement this in java and it worked fine and I have just been porting my work there to C++ so there shouldn't be any issues with the basic maths.

What's up with the two scopes (ie sets of curly braces) that seem to literally serve no purpose?

If your java code is working, one idea is to have both versions print the value of all the variables at various points and see when the values diverge
 

Koren

Member
C kind of goofy. Its taking the values at certain spots in the array and then using them to index into the array. Try unraveling it one step at a time:

x[x[0][0]][x[0][1]]]
First figure out what x[0][0] is, and then figure out what x[0][1] is. Then use those values to get the final values.
C is even more fun...


What about

0[x][0][x][0[x][1]]

?



hint: it's exactly the same ;) C is so low-level that brackets [ ] are in fact just syntaxic sugar.

a is a shortcut for *(a+b)

Thus a[0], *(a+0) and thus 0[a] have exactly the same meaning.
 

Caronte

Member
Anyone here knows how get user input on Swift? I'm supposed to learn how Xcode works more or less (I've just recently started programming) and I decided to try out Swift as well but I'm still running everything I do on the Terminal. How do I get user input? I can't find anything.

To be clear, I'm looking for something like what BufferedReader (or Scanner) does in Java.

Edit: Found a (partial) solution here, I have to convert the string to Int/Double everytime but whatever.
 

Moosichu

Member
What's up with the two scopes (ie sets of curly braces) that seem to literally serve no purpose?

If your java code is working, one idea is to have both versions print the value of all the variables at various points and see when the values diverge

It's a thing I like doing for code hygiene reasons. The big one that is just inside the for-loop is there because I'm going to do some stuff around it, that one is unneeded but I've kept it there to remind me for the other stuff.

The problem ended up being that the number of scene objects was being passed to the function as 48 instead of 1. Really strange but I'm going to investigate that now!
 
It's a thing I like doing for code hygiene reasons. The big one that is just inside the for-loop is there because I'm going to do some stuff around it, that one is unneeded but I've kept it there to remind me for the other stuff.

The problem ended up being that the number of scene objects was being passed to the function as 48 instead of 1. Really strange but I'm going to investigate that now!

I recommend using different functions if you need a different scope, code looks really strange imo. Anyway glad you figured it out
 

Moosichu

Member
I recommend using different functions if you need a different scope, code looks really strange imo. Anyway glad you figured it out

Haha, yeah it will go into different functions eventually. This is just a quick and dirty way of segmenting code off.

This is very much code in progress, don't judge me on it pls :p.

Thank you for the response!
 
I don't know if I should ask here or in the web development thread.
I'm trying to follow this tutorial for Spark: https://www.learnhowtoprogram.com/spark, but I can't seem to be able to retrieve the static resources.
The error I get:
Code:
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource
 'templates/hello.vtl'

My file tree:
bHnJEax.jpg


App.Java:
Code:
import java.util.HashMap;
import spark.ModelAndView;
import spark.template.velocity.VelocityTemplateEngine;
import static spark.Spark.*;

public class App {
  public static void main(String[] args) {

    staticFileLocation("public");

     get("/hello", (request, response) ->{
    return new ModelAndView(new HashMap(), "templates/hello.vtl");
  }, new VelocityTemplateEngine());
  }
}
I couldn't load either the templates or the images. I have no clue of what I'm doing wrong.
 
Did you try staticFileLocation("/public"); instead of staticFileLocation("public") ?

I don't have a system to test this on right now but I will give it a go later tonight if you're still having problems.
 
Did you try staticFileLocation("/public"); instead of staticFileLocation("public") ?

I don't have a system to test this on right now but I will give it a go later tonight if you're still having problems.

Yeah I tried changing/adding/removing the slashes and also tried to change the directory, still nothing.
 

ok so lines a through c i have covered and i can do all the problems involving them

but now theres line d and e that call the "up" function and i dont think ive got it down at all..

for line e what i think im getting is:

Code:
up(int a[x][3], int 1, int 2){

if (2<2) return a[1][1+1]; //but 2 is not less than 2

cout << a[1][2] << endl; //so
return a[x][y];
}
so i blindly go back to the main function and look for [1][2] which is 6

but the output to line e should look like:

6
6
 

Saprol

Member
ok so lines a through c i have covered and i can do all the problems involving them

but now theres line d and e that call the "up" function and i dont think ive got it down at all..

for line e what i think im getting is:

Code:
up(int a[x], int 1, int 2){

if (2<2) return a[1][1+1]; //but 2 is not less than 2

cout << a[1][2] << endl; //so
return a[x][y];
}
so i blindly go back to the main function and look for [1][2] which is 6

but the output to line e should look like:

6
6
There's a cout inside the up() function if y >= 2. So you don't follow the same code path as line (d)
 
There's a cout inside the up() function if y >= 2. So you don't follow the same code path as line (d)

there's no y>=2 anywhere as far as i can tell..

but i get that d doesn't print anything

im just having trouble seeing how the "up" function runs to spit out:

6
6

for line e
 

Saprol

Member
there's no y>=2 anywhere as far as i can tell..

but i get that d doesn't print anything

im just having trouble seeing how the "up" function runs to spit out:

6
6

for line e
You only leave the function early if y<2. The code after the if statement doesn't run.

Code:
up(a, x, y) {
    if (y < 2) return a[x][y+1]; // 2<2 isn't true, don't return
    cout << a[x][y] << endl; // print x[1][2]
    return a[x][y]; // return x[1][2] to where it was called
}

cout << x[1][2] << endl;

>6
>6

It prints it once inside up(). Then the full line (e) will cout the output of up() which was the exact same value because a[x][y] is still a[1][2]
 

mercviper

Member
So for my senior project I'm making my own version of the game Telestrations on Android. It's like a mix of Pictionary and Telephone where you pass along a word, which is drawn, then guessed, then the guess is drawn and so forth until you reach a certain degree of separation and usually the resulting product is nothing close to what you started with. I've more or less figured out the client-server interactions (via post commands and php) so now I'm setting up the MySQL DB for the app.

Because I want the app to present an overview of the chain of events so you can see exactly what point your Tardis becomes a space skyscaper, I need to keep the images and guesses associated to each other. I'm working on creating the table structure for the 'chain' and I'm wondering what the best way to go about it is.

I'm thinking that I have two tables, one for images and one for words. Each link to a previous and next of the appropriate type, with attributes for the author, lobby ID, and index. My only concern is that it's basically a linked list and querying 8 times per chain seems inefficient. Would be pretty easy if I wanted to hard limit each game to 8 degrees total, because then I could just have a record for each 'chain' with 8 entries for images/words, but I want it to be expandable for larger player counts as well as implement an 'infinite' chain for random play when you can't get a group. For the latter gameplay consists of drawing/guessing something and then seeing what it was 8 degrees back, and then getting a push notification of what it becomes 8 degrees later.

Anyway, thoughts?
 

JesseZao

Member
I guess it depends if you want to store the pictures outside of the chain context or not. If you only need the pictures as they exist in the chain you could have two tables. Artist and PictureChain. It would have a composite key with PictureChainID and NumInChain. Then you'd could have an ArtistID and then the picture would be the only other field (whether by a pathname or in a bitarray of some sort).

Otherwise, you could add a picture table and just make the artist picture relationship happen in a join table between artist and picture. You'd only need the pictureId in the PictureChain table then.

Edit: Actually, I'd do this:

PictureChain // PK(PictureChainID, NumInChain) , Word/Phrase, PictureID
Artist // PK(ArtistID) , UserName, ...whatever else you need for this
Picture // PK(PictureID) , Picture
ArtistPictureJoin // PK(ArtistID, PictureID)
 

mercviper

Member
I guess it depends if you want to store the pictures outside of the chain context or not. If you only need the pictures as they exist in the chain you could have two tables. Artist and PictureChain. It would have a composite key with PictureChainID and NumInChain. Then you'd could have an ArtistID and then the picture would be the only other field (whether by a pathname or in a bitarray of some sort).

Otherwise, you could add a picture table and just make the artist picture relationship happen in a join table between artist and picture. You'd only need the pictureId in the PictureChain table then.

Edit: Actually, I'd do this:

PictureChain // PK(PictureChainID, NumInChain) , Word/Phrase, PictureID
Artist // PK(ArtistID) , UserName, ...whatever else you need for this
Picture // PK(PictureID) , Picture
ArtistPictureJoin // PK(ArtistID, PictureID)

Thanks for the insight. I'm using filepaths for the images (because storing files in dbs seem really pretty messy) and after talking to a friend I realized I need to add more attributes (like a chain container) so I can keep track of the individual chains in each lobby. Adding in a step number attribute will also let me sort it easily. I am going to put an image/word combination in each chain similar to your structure though.
 
Haha, yeah it will go into different functions eventually. This is just a quick and dirty way of segmenting code off.

This is very much code in progress, don't judge me on it pls :p.

Thank you for the response!

A small thing I noticed when looking at your code: Try not to use bare arrays in C++ if possible. A std::vector is much more ergonomic, safer and has next to no performance penalty if you're just iterating over it (one pointer dereference to get to the start of the array). If you are able to use C++11, you can even do a Java-esque foreach loop over the vector's objects:
Code:
for (auto& sceneObject: sceneObjects) { ... }

// Instead of this monstrosity from C++98
for (std::vector<SceneObject>::iterator iter = sceneObjects.begin(); iter != sceneObjects.end(); ++iter) { ... }
 

Moosichu

Member
A small thing I noticed when looking at your code: Try not to use bare arrays in C++ if possible. A std::vector is much more ergonomic, safer and has next to no performance penalty if you're just iterating over it (one pointer dereference to get to the start of the array). If you are able to use C++11, you can even do a Java-esque foreach loop over the vector's objects:
Code:
for (auto& sceneObject: sceneObjects) { ... }

// Instead of this monstrosity from C++98
for (std::vector<SceneObject>::iterator iter = sceneObjects.begin(); iter != sceneObjects.end(); ++iter) { ... }

Good point. I've gotten the full basic render working now so I'm going to work on refactoring everything to make it more efficient and cleaner code.

Here's a basic screen (I've only done spheres so far):

However, there is still a long way to go, and now I have to do some grudge work now that I have got something displaying!
 

squidyj

Member
that soft looking lambertian falloff makes me cry inside every time.
it's not supposed to be this way, it's not supposed to be this way :(

More seriously I'm somewhat surprised that in all the graphics and rendering courses I took in college none of my professors even thought to mention color spaces and gamma curves. I guess they thought the display medium and issues with working with it wasn't the topic of the course or something.
 

Pau

Member
Hullo again. This time I'm trying to read lines from a file and do different things with them depending on what the line is.

Code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

struct DNA{
vector<string> header; 
string DNAstring; 
double gcContent;
};

bool isValidDNAchar(char DNAchar_P);
//Post-condition: Returns true if char argument is one of 'a', 'c', 'g', 't'
//Otherwise returns false

bool isValidDNAstring(string DNAstring_P);
//Post-condition: Returns true if string is only made up of valid DNA characters.
//Returns false if any other character exists in the string.
int main() {

	const int MAX_DNA_SIZE = 1000;
	
	DNA dnaArray[MAX_DNA_SIZE];
	
	ifstream dnaFile;
	dnaFile.open("dna.txt");
	string lineFromFile;
	
	ofstream badDNAFile;
	badDNAFile.open("badDNA.txt");
	int badCount = 0;

	//Read each line from file
	int i = 0;
	while(getline(dnaFile, lineFromFile))
	{	
		bool valid = isValidDNAstring(lineFromFile);

		//Add to header vector
		if(lineFromFile[0] == '>')
		{
			dnaArray[i].header.push_back(lineFromFile);
		}
		//Check if validDNAstring
		else if(valid == true)
		{
			dnaArray[i].DNAstring = lineFromFile;
			//Move onto next element in array
			i++;
		}
		else
		{
			badDNAFile << lineFromFile;
			badCount++;
		}	
	}
}

//function definitions
bool isValidDNAchar(char DNAchar_P){
	if((DNAchar_P == 'a') || (DNAchar_P == 'c') || (DNAchar_P == 'g') || (DNAchar_P == 't'))
	{
		return true;
	}
	else
		return false;
}

bool isValidDNAstring(string DNAstring_P)
{
	for(int i=0; i < DNAstring_P.length(); i++)
	{
		char iChar = DNAstring_P[i];
		if(!(isValidDNAchar(iChar)))
		{
			return false;
		}
	}
	return true;
}
My problem is that every line that doesn't start with '>' is being output to the badDNA file even if it is a valid DNA string. I know my isValidDNAstring function works. Is it because getline is including the return carriage and that is making the function return false? How can I check?

Edit: Kind of answered my own question. It seems like it depends on which platform the file was created in, and which platform I'm using to run the program. I have no idea what platform the teacher used to create the original text file. I'm using Mac but we need to make sure the program runs properly in Linux. So I'm guessing I should make it so that it can work on both Mac or Linux...
 

Haly

One day I realized that sadness is just another word for not enough coffee.
Assuming you don't have a debugging environment, just print out `iChar` right before it's about to return false to see what's inside.
 

Pau

Member
Assuming you don't have a debugging environment, just print out `iChar` right before it's about to return false to see what's inside.
I have a debugging environment in Eclipse but no idea how to really use it. :p (We were taught to use another debugger in class but that's on Linux and it kind of sucks.)
But yeah, it was the '\r' character. It works now! :)
 
I have a debugging environment in Eclipse but no idea how to really use it. :p (We were taught to use another debugger in class but that's on Linux and it kind of sucks.)
But yeah, it was the '\r' character. It works now! :)

So if you're not on Linux what are you on that forces you to use Eclipse? OSX has Xcode and Widnows has Visual Studio. Linux is about the only reason to ever use Eclipse, and even that's not a very compelling reason.

Edit: Nvm i see you're using Mac. Why not look up a tutorial on how to use Xcode? It's nowhere near as good as MSVC but it'll still save you tons of time in the long run. I think about 95% of questions people ask in this thread can be answered in under 5 minutes if you know how to use a debugger.
 

Pau

Member
So if you're not on Linux what are you on that forces you to use Eclipse? OSX has Xcode and Widnows has Visual Studio. Linux is about the only reason to ever use Eclipse, and even that's not a very compelling reason.

Edit: Nvm i see you're using Mac. Why not look up a tutorial on how to use Xcode? It's nowhere near as good as MSVC but it'll still save you tons of time in the long run. I think about 95% of questions people ask in this thread can be answered in under 5 minutes if you know how to use a debugger.
Eclipse was what I was told to use for Mac in my first programming class and I never really looked for alternatives. :p I'll look into XCode.
 

Haly

One day I realized that sadness is just another word for not enough coffee.
I googled it briefly and apparently OSX uses the same end-of-lines (\n) as Linux, so:

Windows: \r\n
(pre-OSX) Mac: \r
Linux: \n
OSX: \n

So I think the text file you're working with is authored on an old Mac workstation? But that brings up the question of why you need to deploy it in a Linux environment.
 
I googled it briefly and apparently OSX uses the same end-of-lines (\n) as Linux, so:

Windows: \r\n
(pre-OSX) Mac: \r
Linux: \n
OSX: \n

So I think the text file you're working with is authored on an old Mac workstation? But that brings up the question of why you need to deploy it in a Linux environment.

Probably created the file on Windows, so it has \r\n, and since it's being run on Mac, getline is only removing \n, leaving the \r.
 

NotBacon

Member
So if you're not on Linux what are you on that forces you to use Eclipse? OSX has Xcode and Widnows has Visual Studio. Linux is about the only reason to ever use Eclipse, and even that's not a very compelling reason.

Edit: Nvm i see you're using Mac. Why not look up a tutorial on how to use Xcode? It's nowhere near as good as MSVC but it'll still save you tons of time in the long run. I think about 95% of questions people ask in this thread can be answered in under 5 minutes if you know how to use a debugger.

What are your thoughts on CLion?
 

Pau

Member
I googled it briefly and apparently OSX uses the same end-of-lines (\n) as Linux, so:

Windows: \r\n
(pre-OSX) Mac: \r
Linux: \n
OSX: \n

So I think the text file you're working with is authored on an old Mac workstation? But that brings up the question of why you need to deploy it in a Linux environment.
We're told that all the grading is done in a Linux environment and if the program doesn't work on Linux, we don't get credit. We do have access to a Linux lab, but I work at home on a Mac. This is really the first time it's ever really been a problem. Well, it seems like I'd have had the same problem on Linux anyways since the file was made on Windows.
 

Koren

Member
On windows, the tool linuxlive usb creator create bootable linux usb sticks easily in minutes, that also have "in a window" virtualization capability.

Really handy if you don't want to configure virtualbox and install Linux manually.
 
Top Bottom