2010-10-03 2 views
0

Хорошо, поэтому я пытаюсь создать программу для браузера файлов, и сейчас я нахожусь в основах, но это line здесь:stat (char [], stat), возвращающий -1, когда string.c_str() = "c: /"

fprintf(stderr, "stat returned %i\n", stat(files[curser].c_str(), &st)); 

Говорит, что stat возвращается -1 (сбой), и мне интересно, почему. Может ли кто-нибудь сказать мне? Вот полный источник:

#include <SDL/sdl.h> 
#include <SDL/sdl_image.h> 

#include <SDL/SDL_audio.h> 
#include <SDL/SDL_mixer.h> 

#include <SDL/SDL_ttf.h> 

#include <iostream> 
#include <sstream> // String stream library 
#include <string> 
#include <stdio.h> 
#include <vector> 
#include <fstream> 
#include <ios> 

#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <errno.h> 

#define TICK_INTERVAL 30 

using namespace std; 

extern "C" int SDL_main(int argc, char *argv[]); 

const int SCREEN_WIDTH = 640; 
const int SCREEN_HEIGHT = 480; 
const int SCREEN_BPP = 16; 

SDL_Surface *screen = NULL; 
SDL_Surface *message = NULL; 

bool keys[322]; 

TTF_Font *font = NULL; 
SDL_Color textColor = { 255, 255, 255}; 
SDL_Color highlightColor = { 255, 0, 0}; 

Uint32 TimeLeft(void) 
{ 
    static Uint32 next_time = 0; 
    Uint32 now; 

    now = SDL_GetTicks(); 
    if (next_time <= now) { 
     next_time = now+TICK_INTERVAL; 
     return(0); 
    } 
    return(next_time-now); 
} 


void init(){ 

    // initialize SDL video. If there was an error SDL shows it on the screen 
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0) 
    { 
     fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); 
     SDL_Delay(5000); 
     // exit(EXIT_FAILURE); 
    } 

    // make sure SDL cleans up before exit 
    atexit(SDL_Quit); 
    SDL_ShowCursor(SDL_DISABLE); 

    // create a new window 
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_DOUBLEBUF|SDL_HWSURFACE); 
    if (!screen) 
    { 
     fprintf(stderr, "Unable to set video: %s\n", SDL_GetError()); 
     SDL_Delay(5000); 
    // exit(EXIT_FAILURE); 
    } 

    SDL_WM_SetCaption("Dir Reader", "Dir Reader"); 


    TTF_Init(); 
    //SDL_JoystickEventState(SDL_ENABLE); 
    // joystick = SDL_JoystickOpen(0); 

} 

void cleanup(){ 

    // we have to quit SDL 
    SDL_Quit(); 
    exit(EXIT_SUCCESS); 
} 

void apply_surface (int x, int y, SDL_Surface* source, SDL_Surface* destination){ 

    // make a temporary rectangle to hold the offsets 
    SDL_Rect offset; 

    // give the offsets to the rectangle 
    offset.x = x; 
    offset.y = y; 

    // blit the surface 
    SDL_BlitSurface(source, NULL, destination, &offset); 
} 

void apply_surface (int sourceX, int sourceY, int x, int y, SDL_Surface* source, SDL_Surface* destination){ 

    // make a temporary rectangle to hold the offsets 
    SDL_Rect offset; 
    SDL_Rect sourceRect; 

    // give the offsets to the rectangle 
    offset.x = x; 
    offset.y = y; 
    sourceRect.x = sourceX; 
    sourceRect.y = sourceY; 
    sourceRect.h = source->h; 
    sourceRect.w = source->w; 

    // blit the surface 
    SDL_BlitSurface(source, &sourceRect, destination, &offset); 
} 

void apply_surface (int sourceX, int sourceY, int sourceW, int sourceH, int x, int y, SDL_Surface* source, SDL_Surface* destination){ 

    // make a temporary rectangle to hold the offsets 
    SDL_Rect offset; 
    SDL_Rect sourceRect; 

    // give the offsets to the rectangle 
    offset.x = x; 
    offset.y = y; 
    sourceRect.x = sourceX; 
    sourceRect.y = sourceY; 
    sourceRect.h = sourceH; 
    sourceRect.w = sourceW; 

    // blit the surface 
    SDL_BlitSurface(source, &sourceRect, destination, &offset); 
} 

int getdir (string dir, vector<string> &files) 
{ 
    DIR *dp; 

    struct dirent *dirp; 
    if((dp = opendir(dir.c_str())) == NULL) { 
     cout << "Error(" << errno << ") opening " << dir << endl; 
     return errno; 
    } 

    while ((dirp = readdir(dp)) != NULL) { 
     files.push_back(string(dirp->d_name)); 
    } 

    closedir(dp); 
    return 1337; 
} 

int SDL_main(int argc, char* argv[]) 
{ 
    printf("init.\n"); 
    init(); 

    font = TTF_OpenFont("GOODTIME.ttf", 15); 

    bool done = false; 

    string dir = "C:/"; 
    // dir = dir.substr(0, dir.size() - 1); 

    int curser = 0; 

    while(!done){ 

    vector<string> files = vector<string>(); 

    if(getdir(dir,files) == errno){ 
     printf("error number: %i.\n", errno); 
    } 

     SDL_Event event; 
     while (SDL_PollEvent(&event)) 
     { 
      // Close window : exit 
      if(event.type == SDL_QUIT) 
        done = true ; 

      else if (event.type == SDL_KEYDOWN) 
      { 
       keys[event.key.keysym.sym] = true; 
      } 

      else if (event.type == SDL_KEYUP) 
      { 
       keys[event.key.keysym.sym] = false; 
      } 
     } 

     if (keys[SDLK_x]){ 
      struct stat st; 

      fprintf(stderr, "stat returned %i\n", stat(files[curser].c_str(), &st)); 

      if(S_ISDIR(st.st_mode)){ 

       if(files[curser][0] == '.' && files[curser][1] == '.'){ 
        dir = dir.substr(0, dir.size() - 1); 
        dir = dir.substr(0, dir.find_last_of('/')); 
       } 

       else{ 
        string temp = string(files[curser]); 

        dir += "/"; 
        dir += temp; 
       } 
      } 

      curser = 1; 

      keys[SDLK_x] = false; 
     } 

     if (keys[SDLK_UP]){ 
      curser--; 

      if(curser <= 0){ 
       curser = (int) (files.size() - 1); 
      } 

      keys[SDLK_UP] = false; 
     } 


     if (keys[SDLK_DOWN]){ 
      curser++; 

      if(curser >= (int) files.size()){ 
       curser = 1; 
      } 

      keys[SDLK_DOWN] = false; 
     } 

     SDL_Rect rect; 
     rect.x = 0; 
     rect.y = 0; 
     rect.h = 480; 
     rect.w = 640; 

     SDL_FillRect(screen, &rect, 0x000000); 

     message = TTF_RenderText_Solid(font, dir.c_str(), textColor); 

     apply_surface(0, 0, message, screen); 

     for(int i = 0; i < (int) files.size(); i++){ 

      if(curser == i){ 
       message = TTF_RenderText_Solid(font, files[i].c_str(), highlightColor); 
      } 

      else{ 
       message = TTF_RenderText_Solid(font, files[i].c_str(), textColor); 
      } 

      apply_surface(0, 25 + (i * 15), message, screen); 
     } 

     SDL_Delay(TimeLeft()); 
     SDL_Flip(screen); 
    } 

    cleanup(); 
    return 0; 
} 
+0

проводки 2 страницы исходного кода для одной строки, не помогает при поиске проблемы. –

ответ

2

Да, на самом деле вы можете сказать себе. Если stat не работает, он установит переменную errno, чтобы указать, почему. Вам просто нужно выяснить, что это значит. Вы также можете убедиться, что сам номер files[curser].c_str() действителен, даже если вы заявили, что оно установлено в "c:\".

Даже если это является, что вы заявляете, возможно, stat не любит работать в корневом каталоге в этой форме. Это будет сильно зависеть от используемой вами реализации (вы должны добавить это как тег).

Другими словами, изменить свою линию на что-то вроде:

int x = stat(files[curser].c_str(), &st); 
fprintf(stderr, "stat returned %d '%s' %d\n", x, files[curser].c_str(), errno); 

Для чего это стоит (и что не может быть много), следующая программа отлично работает под VS2008:

#include <stdio.h> 
#include <errno.h> 
#include <sys/stat.h> 

int main(int argc, char* argv[]) { 
    struct stat st; 
    int x = stat("c:\\", &st); 
    fprintf(stderr, "stat returned %d %d\n", x, errno); 
    return 0; 
} 

Выведение:

stat returned 0 0 
+0

Он просто говорит: «stat вернулся -1 0» ... – William

+1

@paxdiablo, или еще лучше использовать 'perror' для удобного для восприятия описания. –

+2

Эта программа не переносима, поскольку она может оценивать errno перед вызовом stat. – Yuliy